Вывод типа Objective-C - PullRequest
       48

Вывод типа Objective-C

8 голосов
/ 16 января 2010

Хорошо, у меня такое чувство, что вы, ребята, сможете быстро указать, почему я так растерялся по этому поводу, но у меня есть вопрос, почему следующее НЕ приводит к ошибке или предупреждению компилятора:

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ];

selectedObject - это NSObject, а name - это имя @property типа int.

Что меня озадачивает, так это то, что компилятор вполне готов предположить, что возвращаемый результат [ self.selectedObject valueForKey:name ] имеет тип NSNumber * (без его типизации), чтобы связать сообщение с вызовом integerValue.

Очевидно, что KVC объединяет необъектные «числовые» типы в NSNumber, но компилятор не может знать, что -valueForKey: вернет NSNumber * в данном конкретном случае.

Почему это не приводит к тому, что предупреждение компилятора в строках "id может не отвечать на" -integerValue ""?

Ответы [ 2 ]

10 голосов
/ 16 января 2010

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

Таким образом, вы можете выбрать, где вы хотите использовать статическую типизацию и где вы хотите использовать динамическую типизацию. Совершенно законно делать что-то вроде этого:

id str1 = @"Hello";
id str2 = [str1 stringByAppendingString:@", world"];

Но обычно вы набираете строки «строго» как NSString s, потому что вы получаете удобство проверки статического типа во время компиляции и прибегаете к динамической типизации только тогда, когда статическая мешает, как в valueForKey ситуация.

4 голосов
/ 05 июля 2018

Время прошло, и теперь у нас есть лучший вывод типов благодаря __auto_type доступно с Xcode 8. Так что теперь вы можете сделать

#define let __auto_type const
#define var __auto_type

let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"

и намного больше

На самом деле, мне это очень понравилось, поэтому я сделал это для удобства.

pod 'SwiftyObjC'
...