Разыменование указателя в Objective-C

может ли кто-нибудь объяснить мне, почему мы не разыменовываем указатель "сейчас" на экземпляр NSDate, когда мы действительно хотим получить данные из этого экземпляра, а не адрес.

NSDate *now = [NSDate date];
NSLog(@"The date is %@", now);

тот факт, почему я смущен, заключается в том, что предыдущий пример NSLog использование в книге Аарона Хиллегаса "Objective-C Programming" было:

NSDate *now = [NSDate date];
NSLog(@"The new date lives at %p", now);

этот код понятен. Нам нужен адрес, мы его получим. Но как получить фактическую дату, просто изменив спецификатор, когда мы продолжаем работать с указкой?

4 ответов


"фактическая дата" - это концепция. "Данные" - это серия байтов. Это не одно и то же.

Если бы вы использовали старые добрые строки в стиле C и printf, вы бы написали следующее:

char *name = "Zakatov";
printf("My name is %s", name);

это так printf функция нуждается в адресе вещи для работы с ней. Вы не передаете "фактические данные", а адрес, потому что он более эффективен для передачи адреса. Передача чего-либо функции означает копирование ее значения в область стека памяти, и гораздо быстрее скопировать адрес (32 или 64 бита), чем скопировать целую строку (несколько байтов или, возможно, КБ или МБ).

поэтому в Objective-C мы все время имеем дело с указателями на объекты, потому что указатели-самый простой способ ссылаться на них. Единственное, что нужно разыменовать указатели (посмотрите на байты), - это система выполнения, например, когда она переводит селекторы сообщений в адреса функций для их выполнения. Ваш код просто обрабатывает указатель как указатель и передает его, не беспокоясь о точном расположении данных на другом конце (байты).


переменной называется now содержит ссылку на место в памяти. Чтобы разыменовать указатель, вы должны сделать то, что вы делаете в C, используя *.

%@ спецификатор формата, используемый для печати объекта description (строка, возвращенная description метод).

int a = 1;
int *b = &a;  // a pointer
int c = *b;   // here you dereference b

в Objective-C, AFAIK вы никогда не разыменовываете указатель на объект (как вы могли бы сделать с указателями на структуры). Это не похоже на ссылки Java, например.

вопрос: какие данные вы хотите получить от NSDate? Вы должны получить эти данные с помощью методов.


вы не можете разыменовать его, потому что все типы Objective-C являются интерфейсами. Что касается полей, вы не знаете, что находится за указателем; на самом деле, ваш NSDate объект, вероятно, даже не является экземпляром NSDate класса. Это просто происходит, чтобы реализовать все методы NSDate выставляет.

указатель будет достаточно для вызова методов, но если вы не можете быть уверены, что вы действительно с NSDate object, вам лучше не пытаться получить доступ к любому полю напрямую. Поэтому, если вы хотите получить информацию от объекта, необходимо использовать его методы.

на %@ спецификатор формата в функциях и методах Cocoa означает, что -[NSObject description] метод должен вызываться на указателе, чтобы знать его текстовое представление.