需求
對(duì)于category厦画,是無(wú)法靜態(tài)的添加成員變量的踩娘。只能使用系統(tǒng)提供的動(dòng)態(tài)的添加方法,objc_setAssociatedObject镐躲。寫(xiě)個(gè)小Demo硫豆,給分類(lèi)增加成員變量
實(shí)現(xiàn)方式
LeviPerson.h 文件中聲明兩個(gè)屬性
#import "LeviPerson.h"
@interface LeviPerson (Test)
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int weight;
@end
LeviPerson.m 中利用關(guān)聯(lián)對(duì)象進(jìn)行實(shí)現(xiàn)
@implementation LeviPerson (Test)
- (void)setName:(NSString *)name
{
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, _cmd);
}
- (void)setWeight:(int)weight
{
objc_setAssociatedObject(self, @selector(weight), @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (int)weight
{
// _cmd == @selector(weight)
return [objc_getAssociatedObject(self, _cmd) intValue];
}
@end
思考與總結(jié)
使用關(guān)聯(lián)對(duì)象的場(chǎng)景:
- 運(yùn)行時(shí)給cagetory添加成員變量
- 有時(shí)需要在對(duì)象中存儲(chǔ)一些額外的信息穗椅,我們通常會(huì)從對(duì)象所屬的類(lèi)中繼承一個(gè)子類(lèi)吁恍。然后給這個(gè)子類(lèi)添加額外的屬性胰舆,改用這個(gè)子類(lèi)册舞。
- 有時(shí)只是給某個(gè)類(lèi)添加一個(gè)額外的屬性蕴掏,完全沒(méi)有必要繼承出來(lái)一個(gè)子類(lèi)。此時(shí)可以使用“關(guān)聯(lián)對(duì)象”调鲸。
- delegate回調(diào)的方法中使用關(guān)聯(lián)對(duì)象盛杰。有時(shí)候在一些delegate回調(diào)的方法中需要處理一些回調(diào)任務(wù)。比如發(fā)起網(wǎng)絡(luò)請(qǐng)求和在delegate回調(diào)的方法中做UI的更新藐石。這樣一來(lái)即供,發(fā)起網(wǎng)絡(luò)請(qǐng)求和在回調(diào)中更新UI的代碼被分散到了兩個(gè)地方,不利于管理和閱讀于微。此時(shí)可以使用“關(guān)聯(lián)對(duì)象”
關(guān)聯(lián)對(duì)象雖然好用逗嫡,但不要濫用,開(kāi)發(fā)者經(jīng)常會(huì)陷入一種困境:正在學(xué)習(xí)或者剛剛學(xué)完某個(gè)技術(shù)株依,就急于在項(xiàng)目中使用驱证,卻忽略了場(chǎng)景。過(guò)多的使用關(guān)聯(lián)對(duì)象將會(huì)降低代碼的可讀性和維護(hù)性勺三,同時(shí)也會(huì)增大調(diào)試的難度雷滚。我們要謹(jǐn)慎的使用關(guān)聯(lián)對(duì)象的內(nèi)存管理策略,知道什么時(shí)候使用OBJC_ASSOCIATION_RETAIN_NONATOMIC什么時(shí)候使用OBJC_ASSOCIATION_ASSIGN吗坚,避免出現(xiàn)循環(huán)引用和一些奇怪的現(xiàn)象祈远。