Является ли переменная 'isa' в objective-C равной 'instanceof' в Java

Простой вопрос: справедливо ли говорить, что переменная экземпляра 'isa' в Objective-C предоставляет ту же функциональность, что и оператор 'instanceof' в Java?

Ответ 1

Это разные понятия.

Один из них является членом структуры, а другой - оператором.

Чтобы подражать строгой интерпретации оператора instanceof в Java, вы можете выполнить сравнение указателей на члене isa:

if(obj->isa == [SomeClass class]) {
  //obj is an instance of SomeClass
}

Но рекомендуется использовать NSObject протокол -isMemberOfClass:, чтобы выполнить это:

if([obj isMemberOfClass:[SomeClass class]]) {
  //obj is an instance of SomeClass
}

Если вам интересно узнать, является ли указанный класс экземпляром или является подклассом другого класса, вы должны использовать метод NSObject protocol -isKindOfClass:.

Ответ 2

Из руководства по программированию Objective-C:

id определяется как указатель на структуру данных объекта:

typedef struct objc_object {
  Class isa;
} *id;

Каждый объект имеет переменную isa, которая сообщает ей, какой класс является экземпляром. Поскольку тип класса сам определяется как указатель:

typedef struct objc_class *Class;

переменная isa часто упоминается как "isa pointer".

Ответ 3

Нет. instanceof больше похож на метод isKindOfClass: в Objective-C, потому что он также оценивает true для подклассов, в то время как указатель isa указывает только на один класс.

Ответ 4

В 64-битных реализациях среды выполнения Objective-C isa стала 64-битной - как и все остальные указатели.

Apple использует умный трюк, чтобы ускорить работу: они полагаются на то, что все 64 бита не используются для адреса, поэтому они используют некоторые из битов для хранения таких вещей, как сохранение счета. Таким образом, им не нужно изменять значение сохранения для объекта в отдельной таблице со всеми последствиями производительности, которые это влечет за собой.

Это означает, что прямое сравнение указателя isa вообще не работает. Это справедливо для OS X и теперь iOS 7 на 64-разрядном A7 (iPhone 5s).

Рассматривать isa как деталь реализации. Не обращайтесь к нему напрямую. Используйте -isMemberOfClass: что будет делать правильная вещь (которая в 64-битных операционных системах теперь включает маскирование части isa).

Дополнительная информация: http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html