首先大家要知道的是 萬物皆對象 類實例化出的對象叫實例對象 類也可以稱為類對象 都是對象,那么這樣我們就可以探索下底層 對象到底是什么
分析源碼
我們可以將.m文件轉換成.cpp 文件 通過以下代碼來將代碼進行轉換
clang -rewrite-objc main.m -o main.cpp
main.m 代碼如下
#import <Foundation/Foundation.h>
@interface LGPerson: NSObject
@property(nonatomic,copy)NSString *name;
@end
@implementation LGPerson
@end
int main(int argc, const char * argv[]) {
LGPerson *person = [[LGPerson alloc]init];
person.name = @"shadiao";
NSLog(@"%@", person.name);
return 0;
}
轉換成后main.cpp 得到關鍵代碼展示 直接在文件中搜你定義的類名LGPerson
extern "C" unsigned long OBJC_IVAR_$_LGPerson$_name;
struct LGPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *_name;
};
// @property(nonatomic,copy)NSString *name;
/* @end */
// @implementation LGPerson
static NSString * _I_LGPerson_name(LGPerson * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_name)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);
static void _I_LGPerson_setName_(LGPerson * self, SEL _cmd, NSString *name) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct LGPerson, _name), (id)name, 0, 1); }
// @end
int main(int argc, const char * argv[]) {
LGPerson *person = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("alloc")), sel_registerName("init"));
((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)person, sel_registerName("setName:"), (NSString *)&__NSConstantStringImpl__var_folders_g6__hcbx3jn56v_lhk2gxkhxn900000gn_T_main_70bb97_mi_0);
NSLog(((NSString *(*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("name")));
return 0;
}
通過.cpp文件可以看出 LGPerson類的定義在底層其實是一個結構體,且結構體中包含 一個結構體成員變量struct NSObject_IMPL NSObject_IVARS; 和自己定義的name屬性
分析下struct NSObject_IMPL NSObject_IVARS; 這是什么,通過全局代碼搜索
struct NSObject_IMPL {
Class isa;
};
是一個NSObject結構體對象 且里面包含一個Class isa 這樣就不難看出 我們定義的LGPerson 也包含一個 isa 那么問題來了 這個isa 是什么? 有什么用?
isa是什么?
其實我們通過查看文檔,蘋果官方是這么說的
A pointer to the class definition of which this object is an instance.翻譯過來就是一個指向當前實例對象所屬的類的指針
因為isa是Class 類型 全局搜 得到
typedef struct objc_class *Class;
是一個objc_class 結構體指針 點進去看
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
里面也有一個Class isa 可以這么理解 isa是什么
總結:isa是一個 objec_class的結構體指針 objc_class 是一個對象類 那么就大致理解了文檔所說的 isa 其實就是一個指向當前實例對象所屬類的指針
isa的作用可以理解為 可以通過分析isa 拿到當前對象所屬類的一些信息
后面我會總結isa 與類的關系
如果理解有問題歡迎大家提出意見和建議
喜歡點個贊???? ???? ????