Есть ли разница между Object
в "Полиморфном" способом с типом id
, чем как NSObject *
?
Каким образом:
NSString* aString = @"Hello";
id anObj = aString;
отличается от:
NSString* aString = @"Hello";
NSObject* anObj = aString;
Есть ли разница между Object
в "Полиморфном" способом с типом id
, чем как NSObject *
?
Каким образом:
NSString* aString = @"Hello";
id anObj = aString;
отличается от:
NSString* aString = @"Hello";
NSObject* anObj = aString;
id
- специальное ключевое слово, используемое в Objective-C для обозначения "какого-то объекта". Он не содержит указателя isa
(isa
, дает объекту доступ к его классу и через класс ко всем классам, на которые он наследует), поэтому вы теряете информацию об объекте времени компиляции.
NSString* aString = @"Hello";
id anObj = aString;
NSObject
содержат указатель isa
.
NSString* aString = @"Hello";
NSObject* anObj = aString;
От Objective-C Является динамическим языком
Рассмотрим следующий код:
id someObject = @"Hello, World!";
[someObject removeAllObjects];
В этом случае someObject укажет на экземпляр NSString
, но компилятор ничего не знает об этом экземпляре за пределами того факта, что его какой-то объект. Сообщение removeAllObjects
определяется некоторыми объектами Cocoa или Cocoa Touch (например, NSMutableArray
), поэтому компилятор не жалуется, хотя этот код генерирует исключение во время выполнения, потому что объект NSString не отвечает на removeAllObjects
.
Переписывание кода для использования статического типа:
NSString *someObject = @"Hello, World!";
[someObject removeAllObjects];
означает, что компилятор теперь генерирует ошибку, потому что removeAllObjects
не объявляется ни в одном общедоступном интерфейсе NSString
, о котором он знает.
id
является общим. Используя id
, вы сообщаете компилятору, что позже вы заполните подробности об использовании. Компилятор предполагает, что любой код, который у вас есть, является правильным и не предупреждает вас ни о чем. Во время выполнения проверяется проверка того, что вы пытаетесь сделать, и вы получите исключение, если ваш код неверен.
NSObject
является специфическим. Используя NSObject
, вы сообщаете компилятору точно, что это за объект. Когда вы пытаетесь вызвать методы на нем, они будут проверены на то, что понимает NSObject
. Если вы допустили ошибку, вы получите ошибки времени компиляции.
Все, что сказано, вы можете просто указать в обоих случаях, чтобы перейти к другому типу класса.
Ваша забота о том, что вы собираетесь делать со ссылкой в будущем. Как правило, использование NSObject
не имеет каких-либо преимуществ.
При использовании id вы можете отправить ему какое-либо известное сообщение, а при использовании NSObject * вы можете отправлять сообщения, объявленные NSObject (не методы какого-либо подкласса), иначе он будет генерировать предупреждение.