С помощью переменной id
вы можете отправить ей любое известное сообщение, и компилятор не будет жаловаться. С переменной типа NSObject *
вы можете отправлять ей только сообщения, объявленные NSObject (но не методы какого-либо подкласса), иначе оно выдаст предупреждение. В общем, id
это то, что вы хотите.
Дальнейшее объяснение: Все объекты по существу имеют тип id
. Смысл объявления статического типа заключается в том, чтобы сказать компилятору: «Предположим, что этот объект является членом этого класса». Поэтому, если вы отправите ему сообщение, которое класс не объявляет, компилятор может сказать вам: «Подождите, этот объект не должен получить это сообщение!» Кроме того, если два класса имеют методы с одним и тем же именем, но разными сигнатурами (то есть тип аргумента или возвращаемый тип), он может угадать, какой метод вы подразумеваете под классом, объявленным для переменной. Если он объявлен как id
, компилятор просто поднимет руки и скажет: «Хорошо, у меня недостаточно информации. Я выбираю сигнатуру метода случайным образом». (Однако, как правило, это не поможет объявлением NSObject*
. Обычно конфликт происходит между двумя более конкретными классами.)