Когда вы используете * в определениях переменных (в Objective-C)? - PullRequest
2 голосов
/ 11 февраля 2010

Я все еще путаюсь с Objective-C. Иногда вы объявляете переменную так:

NSRect rect;

А иногда так:

NSValue *value;

Я никогда не знаю, когда добавить *, поэтому я всегда искал его в документации Apple. Я знаю разницу между значением и указателем на объект.

Но существуют ли жесткие и быстрые правила относительно того, когда я объявляю значение и когда я объявляю указатель? Что-нибудь, чтобы было легче запомнить? Или я должен знать (например, искать), какое значение NSSomething является значением, а какое - объектом?

Спасибо!

Ответы [ 5 ]

5 голосов
/ 11 февраля 2010

Коротко и просто: да, вы должны помнить это для каждого типа, но это будет очень естественно через некоторое время.

Вопрос не столько в том, «какой NSSomething является значением, а какой является объектом» (точнее: какой NSSomething является скалярным типом данных или структурой, а какой - классом). Даже если вы не увидите и не будете использовать объявления вроде:

NSRect *pointerToARect;
NSInteger *pointerToAnInteger;

очень часто, они идеально подходят и время от времени необходимы. Таким образом, для скаляров (простых типов данных, таких как NSInteger) и структур, оба варианта являются действительными, и какой вариант вы используете, зависит от того, нужен ли вам указатель или фактическая вещь.

В случае объектов все ваши переменные всегда должны быть указателями, поскольку объекты можно размещать только в куче, а не в стеке. Так что в отличие от приведенных выше примеров, это:

NSValue myValue; // invalid!

неверно и не будет компилироваться.

5 голосов
/ 11 февраля 2010

Если переменная является указателем на объект, вы используете *. Исключение составляет id (что подразумевается *). Такие вещи, как NSRect и NSRange - это просто структуры, обернутые вокруг основных переменных C.

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

0 голосов
/ 11 февраля 2010

Вы не используете звездочку для NSRect, потому что это просто структура C, а не класс Objective-C. Многие из примитивов Фонда являются структурами, такими как NSPoint и NSRange. Вы можете удерживать Option и дважды щелкнуть мышью по типу, чтобы вызвать его документацию, или удерживать Command и дважды щелкнуть мышью, чтобы перейти к определению заголовка и посмотреть, что это такое.

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

0 голосов
/ 11 февраля 2010

Как указано в Foundation Reference , ниже приведены типы данных и, следовательно, структуры. Вы должны объявить их как значения.

   * NSAppleEventManagerSuspensionID
   * NSByteOrder
   * NSComparator
   * NSComparisonResult
   * NSDecimal
   * NSEnumerationOptions
   * NSHashEnumerator
   * NSHashTable
   * NSHashTableCallBacks
   * NSHashTableOptions
   * NSInteger
   * NSMapEnumerator
   * NSMapTable
   * NSMapTableKeyCallBacks
   * NSMapTableOptions
   * NSMapTableValueCallBacks
   * NSPoint
   * NSPointArray
   * NSPointPointer
   * NSRange
   * NSRangePointer
   * NSRect
   * NSRectArray
   * NSRectEdge
   * NSRectPointer
   * NSSearchPathDirectory
   * NSSearchPathDomainMask
   * NSSize
   * NSSizeArray
   * NSSizePointer
   * NSSocketNativeHandle
   * NSSortOptions
   * NSStringEncoding
   * NSSwappedDouble
   * NSSwappedFloat
   * NSTimeInterval
   * NSUncaughtExceptionHandler
   * NSUInteger
   * NSZone

Ответ Шерману: Вы правы, я не внимательно просмотрел список - меньшинство определений действительно не было структурами. Однако эти типы данных не упоминаются как указатели: например, вы никогда не будете использовать «NSRangePointer *».

Ответ на bbum: Даже если вы могли бы явно выделить память в куче для этих структур и ссылаться на нее через указатель, это плохая практика в Какао.

0 голосов
/ 11 февраля 2010

Общее правило использования * в моем случае - это когда я использую один из встроенных в Apple классов / фреймворков. Все, что вам нужно для запуска alloc; и init: - это то, на что вы держите ссылку, а не фактическую вещь (например, int или значение с плавающей точкой).

...