Должен ли я быть кастом при возврате id из методаjective-c или нет? - PullRequest
3 голосов
/ 17 июня 2011

Для гуру Objective-C:

Предположим, у меня есть простой метод, подобный так:

-(id)getValue{ return [NSNumber numberWithDouble:5.0]; }

Теперь предположим, что в каком-то другом методе я вызываю метод getValue (id) следующим образом:

NSNumber* myValue = [self getValue];

или что, если я вместо этого назову это так:

NSNumber* myValue = (NSNumber*)[self getValue];

Вопрос: очевидно, что эти строки эквивалентны, но одна из них использует явное приведение. Так каков правильный или лучший способ сделать это? Мне кажется, что приведение не является необходимым, поскольку, когда оно помещено в указатель myValue, оно в любом случае будет безопасным с точки зрения типов (что я и хочу), поэтому приведение в принципе бессмысленно.

Позвольте мне просто добавить, что я уверен, что люди укажут: почему бы вам просто не вернуть (NSNumber *) из метода getValue, но в моем случае я хочу иметь возможность возвращать все, что я хочу, так же, как встроенный в NSDictionary класс возвращает id при вызове: objectForKey, потому что он позволяет помещать в него любой тип NSObject или подкласс. Другими словами, мой метод getValue не всегда будет возвращать NSNumber. Также подумайте, что этот пример надуман, потому что я просто обеспокоен тем, следует ли разыгрывать или нет.

Заранее спасибо,

-Ральф

1 Ответ

5 голосов
/ 17 июня 2011

Единственная причина для приведения объектов - сделать счастливым компилятор.(Иногда это также помогает удобочитаемости.) Например, вам нужно приводить при доступе к свойству непосредственно к объекту, который вы получаете из массива или словаря:

((Foo *)[myArray objectAtIndex:0]).bar;

Если вы этого не делаетеПри приведении, компилятор не может выполнить поиск свойства и будет жаловаться.

Когда вы получаете объект из метода, который возвращает id, компилятору невозможно узнать, каков его фактический тип.является.На самом деле нет никакой «безопасности типов», потому что id - это общий указатель;все, что может и будет применять компилятор, - это то, что метод говорит, что он возвращает некоторый объект Objective-C.Он очень рад назначить универсальный указатель для любого типизированного указателя. * (Очевидно, что это на самом деле преимущество для контейнеров.) Поскольку тип переменной, которой вы назначаете, уже документирует возврат фактический типа, я бы сказал, что нет необходимости в приведении.

Кстати, вы не должны вызывать свой метод getX.Это имеет особое значение в какао;методы, которые «получают» что-то, передают указатель на указатель, который затем заполняется методом.См. -[NSArray getObjects:range:] в качестве примера.


* Тип будет принудительно применяться во время выполнения, конечно, в том смысле, что отправка сообщений, на которые объект не отвечаетвызовет ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...