目录
回顾:
.objc_object 和 objc_class是继承关系,class继承自object。
.像person和NSObject,person和objc_object没有继承等关系,只是一个上层,一个底层,然后NSObject是按照objc_class的模板创建的。
.id 是 objc_object *类型的
.class是objc_class *类型的
一、属性、成员变量、实例变量的区别
属性=带下划线的成员变量+setter+getter方法
实例变量=特殊的成员变量(实例化的),比如NSObject *objc,UIButton等。
查看main.cpp文件:终端cd到源码的main.m所在文件夹下,执行“clang -rerite-objc main.m -o main.cpp”即可编译出main.cpp文件。
@interface LGPerson : NSObject
{
// STRING int double float char bool
NSString *hobby; // 字符串
NSObject *objc; // 结构体
}
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, strong) NSString *name;
@end
可以看出编译成cpp文件以后,LGPerson_IMP里除了我们的成员变量hobby、objc外,还多了几项和属性名称相同但名字前带下划线的成员变量_nickName和 _name。
同时还生成了属性nickName和name的setter、getter方法:
其中getter方法都是通过self指针偏移来获取值的,而setter方法则不同,我们发现nickName属性的setter方法是调用了objc_setProperty(),而name属性则是通过指针平移的方式给相应位置赋值的,这是为什么呢?我们放到 三、setter方法底层原理 中去解答。
{
{(struct objc_selector *)"nickName", "@16@0:8", (void *)_I_LGPerson_nickName},
{(struct objc_selector *)"setNickName:", "v24@0:8@16", (void *)_I_LGPerson_setNickName_},
{(struct objc_selector *)"name", "@16@0:8", (void *)_I_LGPerson_name},
{(struct objc_selector *)"setName:", "v24@0:8@16", (void *)_I_LGPerson_setName_},
比如"@16@0:8"这代表什么意思?我们先来补一下编码表的知识~
二、sel&imp 编码表补充
sel:方法编号(相当于一本书的目录名称)
imp:函数指针地址(相当于一本书的目录页码)
ivar_getTypeEncoding()方法 shirt+command+0打开苹果文档搜索该方法,
底部Type Encodings链接点击进入 获取编码表。
这里贴出来看一下:
Code |
Meaning |
---|---|
|
A |
|
An |
|
A |
|
A
|
|
A |
|
An |
|
An |
|
An |
|
An |
|
An |
|
A |
|
A |
|
A C++ |
|