2009-07-09 2 views
53

Я только что начал изучать Objective-C, исходя из фона VB .Net и C# .Net. Я понимаю использование указателей, но в примерах Objective-C я вижу звездочку, размещенную в нескольких разных местах, и, по мере возможности, поиск, я не смог найти ответ о том, почему это так. Каждый поиск, который я стараюсь, вызывает всевозможные объяснения о указателях (что мне действительно не нужно), но ни одного упоминания о причинах/эффектах разных мест размещения звездочки. Вот несколько примеров, которые я видел:Размещение звездочки в Objective-C

NSString *string; 
NSString * string; 
(NSString *) string; 
NSString* string; 

Что означают эти разные позиции звёздочки? Я уверен, что это простой ответ, но разочарование не в том, чтобы найти его в любом учебнике и справочной документации Apple или в Интернете до сих пор.

Может кто-нибудь, пожалуйста, закончите мое несчастье и ответьте на этот озадачивающий вопрос? Благодаря!

+1

@ john_5101 Если вы поместили четыре пробела перед текстом в виде кода, он будет рассматривать его как код и сделать его правильным (я считаю, что это ответ на проблему, с которой вы уклоняетесь от своего вопроса). –

+0

Можем ли мы считать это возможностью просто случайно объявить один из них «правильным» способом и остановить эту бессмыслицу? – twiz

ответ

3

там фактически все эквиваленты: указатель на nsstring !!

19

Нет никакой разницы - это вопрос стиля. Все они объявляют переменную с именем string, которая является указателем на NSString. Скобки необходимы в некоторых контекстах (особенно для объявлений методов), чтобы уточнить, что это объявление типа.

+0

Я думаю, вы имеете в виду, что нет разницы в пробеле вокруг звездочки, но, как указали другие, 3-я строка (сам по себе) приведение в NSString * (которое можно использовать, если строка является «идентификатором» CFStringRef) или, возможно, частью объявления метода Objective-C. По мне, по крайней мере, ваш смысл был ясен. –

+4

Я все же предпочитают последнюю форму (исходящую из фона C++): она четко определяет тип и объект. Вот небольшая дискуссия по этому вопросу от Stroustrup: http://www.research.att.com/~bs/bs_faq2. html # whitespace – PlagueHammer

23
1. NSString *string; 
2. NSString * string; 
3. (NSString *) string; 
4. NSString* string; 

1, 2 и 4 точно идентичны. Это все стиль. Выбирайте все, что хотите, или смешивайте.

Вариант № 3 имеет и другое значение, оно используется при кастинге. Например:

t = (NSString *)string ; 

бросит string к NSString указателю.

Но выбор № 3 - это синтаксис, который вы, вероятно, используете в файле .h или в определении функции в файле .m. Внутри фактической функции в коде, который «запускается», он имеет другое значение.

+0

Несмотря на то, что это допустимый тип, никогда не должно быть необходимости явно бросать объект в NSString * - если вы опускаетесь от id или void *, вы можете делать трансляцию неявно, а если вы повышаете уровень из подкласса (например, NSMutableString), вы также можете сделать это неявно. –

+1

+1, но оператор 3 фактически является nop - вы вряд ли захотите использовать эту строку где угодно. Вы использовали бы его как часть выражения для приведения 'string' в NSString *, но он недействителен как объявление. Конечно, я не знаком с Objective-C, поэтому, если в этом диалекте C используется выражение 3, пожалуйста, сообщите мне, что я ношу глупость, и я удалю этот комментарий. –

+0

Согласен. И спасибо, хорошая точка. Но синтаксически это актерский состав. Я просто хотел указать на это, потому что определенно будут времена, когда плакат OP увидит это. – marcc

6

Не имеет значения, где вы помещаете звездочку, все инструкции создают указатели типа NSString.

При использовании нескольких имен переменных в одной строке вы должны написать звездочку для каждой переменной.

NSString * nsstring, * nsstring2; 
+9

... что является одной из самых уродливых вещей в C, и поэтому их следует избегать. –

2

1, 2 и 4 эквивалентны и определяют указатель на NSString. Мои личные предпочтения - подражать K & R как можно больше, поэтому я хотел бы использовать NSString *string;

хотя действительное заявление действительно ничего не делает сам по себе.

$ cat foo.m 
#include <Cocoa/Cocoa.h> 

void foo() 
{ 
    NSString *string; 

    (NSString*) string; // doesn't do anything 
    42; // doesn't do anything either 
} 

$ gcc -Wall -c foo.m 
foo.m: In function 'foo': 
foo.m:7: warning: statement with no effect 
foo.m:8: warning: statement with no effect 
6
1. NSString *string; 
2. NSString * string; 
3. (NSString *) string; 
4. NSString* string; 

1,2 и 4 эквивалентны. На языке C (и надмножестве Objective-C) укажите синтаксис, который нечувствителен к пробелу. Таким образом, вы можете свободно добавлять пространства, в которых вы выбираете стиль. Весь соответствующий синтаксис разделяется символами без пробелов (например, {, }, ; и т. Д.) [1].

3 является либо типом литого (сообщение компилятору C для использования типа NSString* независимо от объявленного типа string.В Objective-C редко возникает необходимость в литье экземпляров объектов. Вы можете использовать тип id для переменных, которые могут ссылаться на экземпляры любого типа объекта.

В объявлениях методов синтаксис 3 (иногда без конечной точки с запятой) используется для объявления типа параметров метода. Метод Objective-C может выглядеть следующим образом:

- (void)myMethodThatTakesAString:(NSString*)string; 

В этой декларации, тип аргумента с именем string является тип NSString* (ведущий - указывает метод экземпляра, как оппонировать метод класса). Способ декларации с более чем одним параметром может выглядеть следующим образом:

- (void)myMethodTakingAString:(NSString*)string andAnInteger:(NSInteger)intParam; 

[1] Это по сравнению с языками, как Python, которые используют пробелы в качестве блока разделителя.

5

Нет никакой разницы, где * размещается в объявлении указателя, не имеет значения.

3

Существует абсолютно никакой разницы между ними.

+0

Существует стилистическая разница, которая сильно отличается от перспективы читаемости кода. @ me1974 ответ правильный ... это должно быть, как показано apple – Ondrej

+0

Только стилистика, а «читаемость» субъективна. – coneybeare

+0

хорошо сделать собственную версию рекомендуемого стиля не может иметь другого эффекта, но уменьшить читаемость для большинства разработчиков ... – Ondrej

4

Не имеет значения, размещение пробелов не имеет значения.

32

Нет никакой разницы, однако вы должны знать, что только первый «токен» (так сказать) определяет имя типа, а * не является частью имени типа. То есть:

NSString *aString, bString; 

Создает один указатель-to NSString, и один NSString. Для того, чтобы получить и как указатели, сделать что-либо:

NSString *aString, *bString; 

или:

NSString *aString; 
NSString *bString; 
+0

Поскольку исходный вопрос касался размещения '*', я немного изменил ваш ответ, чтобы уменьшить путаницу. –

+2

... и, конечно, вы не можете объявить переменную NSString, которая не является указателем (вне диалекта POC), поэтому первый пример кода не будет компилироваться. – Chuck

+2

Будет ли 'NSString * aString, bString' создавать 2 указателя на NSStrings? – micnguyen

4

Там нет абсолютно никакой разницы. NSString * mystring и NSString * myString идентичны.

3

* работает точно так же, как и в стандартном С.

это хороший учебник по сдаче * в разных местах и ​​что она делает: http://boredzo.org/pointers/

0

в xcode4 документации образец коде вы можете увидеть 3. все время, например, в MoveMeView.m

#if 1 

- (void)growAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 

#define MOVE_ANIMATION_DURATION_SECONDS 0.15 

[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS]; 
placardView.transform = CGAffineTransformMakeScale(1.1f, 1.1f); 
/* 
Move the placardView to under the touch. 
We passed the location wrapped in an NSValue as the context. 
Get the point from the value, then release the value because we retained it in touchesBegan:withEvent:. 
*/ 
NSValue *touchPointValue = (NSValue *)context; 
placardView.center = [touchPointValue CGPointValue]; 
[touchPointValue release]; 
[UIView commitAnimations]; 
} 
0

там не может быть каких-либо различий в альтернативах 1, 2 и 4 на компьютере, но есть другие читатели кода.

Поскольку объяснения, как https://stackoverflow.com/a/1521382 и https://stackoverflow.com/a/16040884 и https://www.tutorialspoint.com/objective_c/objective_c_pointers.htm использовать первый вариант:

1. NSString *string;

и все дополнительные переменные должны иметь собственные звездочки, как в:

NSString *aString, *bString;

мое скромное предложение что мы используем альтернативу 1 в качестве стандарта.

Смежные вопросы