有時候,我們會想在別人的類中添加一個屬性.這個屬性只會在自己的模塊用到,在其它地方無用.那么現在就用兩個方案:
1,直接在原類中添加一個屬性
2,寫一個分類,在分類中將這個屬性加進去.
這兩種方案實現的異同:
同:都能達到在已有的類中添加一個屬性的需求.
異:
第一種方案優點:實現簡單.缺點:破壞了已有的類的封裝,會給后續開發者帶來疑惑.結論:笨方法
第二種方案有點:能與已有類完全分開,保持了模塊化的獨立性.貌似沒有缺點,如果一定要找出一個缺點,那就是一個字"難",因為要用到個高大上的運行時機制才能達到目的.結論:高端大氣上檔次!
具體的實現:(跳過第一種方案,直接介紹第二種方案)
比如現在已經有了一個Person類,類中已有兩個屬性:name,與age.本來有這兩個類中哦這兩個屬性就已經夠需求了.但是在另一個獨立的模塊中要求添加一個address的屬性,這個屬性的有無不會影響到之前已有的模塊.
已有類如下:
.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) int age;
@end
.m
#import "Person.h"
@implementation Person
@end
分類的實現如下:
.h
#import "Person.h"
@interface Person (Address)
@property (nonatomic, copy) NSString* address;
@end
.m
#import "Person+Address.h"
@implementation Person (Address)
@end
到這里貌似可以了.回到main.m中試試.shixian:
Person* p = [[Person alloc] init];
p.address = @"天朝";
NSLog(@"address-->%@",p.address);
這么簡單!!!盡然木有報錯.編譯一下,問題就來了,log是:
-[Person setAddress:]: unrecognized selector sent to instance 0x100110e50.....
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person setAddress:]: unrecognized selector sent to instance 0x100110e50'
你的英語好,你就好好理解吧.
大家都看到,在我實現的分類中,就定義了一個屬性,在.m中什么也沒有做,怎么可以能就這么簡單,還沒有用上高大上的運行是機制呢!!
分類.m修改如下
#import "Person+Address.h"
#import <objc/runtime.h>
@implementation Person (Address)
#pragma mark - address
static char AddressKey;//類似於一個中轉站,參考
- (void)setAddress:(NSString *)address {
objc_setAssociatedObject(self, &AddressKey, address, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*)address {
return objc_getAssociatedObject(self, &AddressKey);
}
@end
OK了,現在可以放心的使用,放心的編譯了.在這個.m文件中主要由了一個運行時機制.記得導入頭文件:#import <objc/runtime.h>
還用到objc_setAssociatedObject與objc_getAssociatedObject兩個函數.具體什么意思,建議去看看文檔吧.
謝謝大神閱讀本博客,若有不當之處,望指導!QQ:771722918