
注意在ARC環(huán)境下:
1、在類中
@property的本質(zhì):
@property = ivar(實(shí)例變量) + getter/setter方法聲明 + getter/setter方法實(shí)現(xiàn);
當(dāng)在類中使用@property聲明屬性時(shí),無論是在.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類的.h中默認(rèn)添加一個(gè)名為_name的成員變量,setName和name:兩個(gè)方法(getter/setter)的聲明,如:
@interface Person : NSObject
{
NSString *_name;
}
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
并且在Person類的.m中添加setName和name:兩個(gè)方法(set/get)的實(shí)現(xiàn),如:
- (void)setName:(NSString *)name{
_name = name;
}
- (NSString *)name{
return _name;
}
2、在分類中
@property的本質(zhì):
@property = getter/setter方法聲明;
可以發(fā)現(xiàn),當(dāng)我們?cè)诜诸愔惺褂聾property聲明屬性時(shí),只是生成了getter/setter方法的聲明,并不會(huì)自動(dòng)生成ivar(實(shí)例變量) 和 getter/setter方法的實(shí)現(xiàn)。
例如:
@interface Person (test)
@property (nonatomic, copy) NSString *name;
@end
此時(shí),只是在分類的.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ì)通過runtime添加關(guān)聯(lián)對(duì)象,來間接的實(shí)現(xiàn)給分類添加屬性。如下:
#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
分類(Category)具體的實(shí)現(xiàn)原理,這里暫不詳細(xì)說明;