關於iOS Category實現添加屬性及成員變量


iOS分類:

很多說法是只能添加方法,而不能添加成員變量或屬性。

有些人可能知道,這種說法是不嚴謹的,並不是絕對不能添加變量。

解釋如下:

我們知道在一個類中用@property聲明屬性,編譯器會自動幫我們生成_成員變量setter/getter,但分類的指針結構體中,根本沒有屬性列表。所以在分類中用@property聲明屬性,既無法生成_成員變量也無法生成setter/getter。 
因此結論是:我們可以用@property聲明屬性,編譯會通過,但run之后就會崩潰。

 

問題來了。。

既然報錯的根本原因是使用了系統沒有生成的setter/getter方法,可不可以在手動添加setter/getter來避免崩潰,完成調用呢? 
其實是可以的。由於OC是動態語言,方法真正的實現是通過runtime完成的,雖然系統不給我們生成setter/getter,但我們可以通過runtime手動添加setter/getter方法。那具體怎么實現呢?

舉例如下:

分類.h

#import "Programmer.h"

@interface Programmer (Category)

@property(nonatomic,copy) NSString *nameWithSetterGetter;           //設置setter/getter方法的屬性

- (void) programCategoryMethod;                                     //分類方法

@end

分類.m

#import "Programmer+Category.h"
#import <objc/runtime.h>

static NSString *nameWithSetterGetterKey = @"nameWithSetterGetterKey";
@implementation Programmer (Category)
- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter { objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY); } - (NSString *)nameWithSetterGetter { return objc_getAssociatedObject(self, &nameWithSetterGetterKey); } - (void)programCategoryMethod { NSLog(@"實現分類方法"); } @end

 

重點就是兩個runtime實現方法,如果不寫這個,只要你申明了屬性,運行肯定會報錯;如果加了這兩個方法,就能運行通過了,而且,我們在其他地方也能正常使用了

  Programmer *programmer = [[Programmer alloc]init];
    
    //通過runtime實現了setter/getter
    programmer.nameWithSetterGetter = @"有setter/getter";    //調用setter,成功
    NSLog(@"%@",programmer.nameWithSetterGetter);            //調用getter,成功

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM