id
стирает тип, и это равносильно тому, что «этот объект реагирует на любой селектор, видимый для перевода».конечно, ваша ответственность за обеспечение правильности вашей программы при удалении типов (а также при их типизации).
Если тип был NSObject
, то компиляторсказал бы "NSObject может не отвечать на селектор ", если селектор не был объявлен в интерфейсе NSObject или протоколах, которые он принимает.В этом случае вы также можете добавить приведение типа для приведения его к ожидаемому типу.
Со строгими / правильными типами компилятор может подключиться и помочь вам, что прекрасно, потому что ObjC очень динамичныйlanguage.
id
особенно полезен при использовании (или построении) типов коллекций.Добавление объекта не будет проблемой, если вы не определили новый корневой тип (не наследуется от NSObject).Для получения значения из коллекции потребовалось бы приведение типа, если бы мы использовали его как нечто отличное от нашего базового класса (NSObject).
Objective-C не поддерживает обобщенные элементы - вы, например, не можете объявить NSArray
из NSString
с.Вы можете заполнить NSArray
с помощью NSString
s и передать это через id
для более естественного письменного стиля, когда безопасность типов не сохраняется (а-ля generics).
Итак, давайте расширим это снекоторый реальный код.
Пример A
NSString * string = [array objectAtIndex:0]; // << trust me (via id)
return [string length];
-or-
return [[array objectAtIndex:0] length]; // << trust me (via id)
Пример B
А теперь, скажем, id
недоступны, и мы исправляем все наши предупреждения компилятора, потому что это правильно:
NSString * string = (NSString*)[array objectAtIndex:0]; // << typecast == trust me
return [string length];
-or-
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me
id
не определяет его значение во время выполнения и не выполняет какой-либо NSObject.Объекты ObjC не выполняют неявное продвижение, они просто проводят указатель без формального продвижения.
Что касается вашего примера, я фактически объявляю свои делегаты и параметры как объекты NSObjects с протоколами:
NSObject<MONShapeDelegate>* delegate;