注意在ARC環(huán)境下:
1睦裳、在類(lèi)中
@property的本質(zhì):
@property = ivar(實(shí)例變量) + getter/setter方法聲明 + getter/setter方法實(shí)現(xiàn);
當(dāng)在類(lèi)中使用@property聲明屬性時(shí),無(wú)論是在.h中的還是在.m中撼唾,
編譯器會(huì)自動(dòng)生成一個(gè)帶下劃線的實(shí)例變量 + 對(duì)應(yīng)的getter/setter方法的聲明 + 對(duì)應(yīng)的getter/setter方法的實(shí)現(xiàn)廉邑;
例如:
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end
此時(shí),會(huì)給Person類(lèi)的.h中默認(rèn)添加一個(gè)名為_(kāi)name的成員變量倒谷,setName和name:兩個(gè)方法(getter/setter)的聲明蛛蒙,如:
@interface Person : NSObject
{
NSString *_name;
}
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
并且在Person類(lèi)的.m中添加setName和name:兩個(gè)方法(set/get)的實(shí)現(xiàn),如:
- (void)setName:(NSString *)name{
_name = name;
}
- (NSString *)name{
return _name;
}
2渤愁、在分類(lèi)中
@property的本質(zhì):
@property = getter/setter方法聲明牵祟;
可以發(fā)現(xiàn),當(dāng)我們?cè)诜诸?lèi)中使用@property聲明屬性時(shí)抖格,只是生成了getter/setter方法的聲明诺苹,并不會(huì)自動(dòng)生成ivar(實(shí)例變量) 和 getter/setter方法的實(shí)現(xiàn)。
例如:
@interface Person (test)
@property (nonatomic, copy) NSString *name;
@end
此時(shí)雹拄,只是在分類(lèi)的.h中自動(dòng)生成了setName和name:兩個(gè)方法(set/get)的聲明收奔,如:
@interface Person (test)
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
并且,在.m中有會(huì)提示:
提示需要提供setter/getter方法的實(shí)現(xiàn)办桨;
如果筹淫,不提供setter/getter方法的實(shí)現(xiàn),在使用是會(huì)報(bào)錯(cuò)unrecognized selector呢撞,
如下:
所以损姜,一般我們會(huì)通過(guò)runtime添加關(guān)聯(lián)對(duì)象,來(lái)間接的實(shí)現(xiàn)給分類(lèi)添加屬性殊霞。如下:
#import "Person+test.h"
#import <objc/runtime.h>
@implementation Person (test)
- (NSString *)name {
return objc_getAssociatedObject(self, @selector(name));
}
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
分類(lèi)(Category)具體的實(shí)現(xiàn)原理摧阅,這里暫不詳細(xì)說(shuō)明;