《EffectiveObjective-c 2.0》第四章 協(xié)議與分類

第23條:通過委托與數(shù)據(jù)源洗衣進(jìn)行對(duì)象間通信

  1. 委托模式為對(duì)象提供 一套接口,使其可由此將相關(guān)事件告知其他對(duì)象。
  2. 將委托對(duì)象應(yīng)該支持的接口定義成協(xié)議,在協(xié)議中把可能需要處理的事件定義成方法。
  3. 若有必要,可實(shí)現(xiàn)含有位段的結(jié)構(gòu)體,將委托對(duì)象是否能相應(yīng)相關(guān)協(xié)議方法這一信息緩存至其中。
    .h文件
@protocol NetworkFetchDelegate

- (void)fetchData;

@end

@interface NetworkFetchViewController : UIViewController

@property (nonatomic, weak) id<NetworkFetchDelegate> delegate;

@end

.m 文件

#import "NetworkFetchViewController.h"

@interface NetworkFetchViewController () {
//位段操作,使用此操作可以提高操作性能
    struct {
        unsigned int didReceiveData : 1;
    } _delegateFlags;
}

@end

@implementation NetworkFetchViewController

- (void)setDelegate:(id<NetworkFetchDelegate>)delegate{
    _delegate = delegate;
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    [(NSObject *)delegate respondsToSelector:@selector(fetchData)];
    CFAbsoluteTime endTime = (CFAbsoluteTimeGetCurrent() - startTime);
    NSLog(@"Linked in %f ms", endTime *1000.0);
    
    _delegateFlags.didReceiveData = [(NSObject *)delegate respondsToSelector:@selector(fetchData)];
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    if (_delegateFlags.didReceiveData) {
        CFAbsoluteTime endTime = (CFAbsoluteTimeGetCurrent() - startTime);
        NSLog(@"viewDidLoad in %f ms", endTime *1000.0);
        [_delegate fetchData];
    }
}

@end

輸出結(jié)果

2017-08-21 17:36:50.149930+0800 WCCTestProj[8188:1687351] Linked in 0.001967 ms
2017-08-21 17:36:50.151034+0800 WCCTestProj[8188:1687351] viewDidLoad in 0.000000 ms
2017-08-21 17:36:50.151151+0800 WCCTestProj[8188:1687351] ViewController ----  fetchData

如果使用位段的話,性能提高1000多倍。如果是頻繁調(diào)用的話性能提高更多的。
參考 位段介紹

第24條:將類的實(shí)現(xiàn)代碼分散到便于管理的數(shù)個(gè)分類之中

  1. 使用分類機(jī)制把類的實(shí)現(xiàn)代碼劃分成易于管理的小塊。
  2. 將應(yīng)該視為“私有”的方法歸入名叫Private的分類中,已隱藏實(shí)現(xiàn)細(xì)節(jié)。

第25條:總是為第三方類的分類名稱加前綴

  1. 向第三方類中添加分類時(shí),總應(yīng)該給其名稱加上你專用的前綴。
  2. 向第三方類中添加分類時(shí),總應(yīng)給其中的方法名加上你專用的前綴
@interface NSString (ABC_HTTP)//分類名加前綴
- (NSString *)abc_urlEncodedString;//方法名加前綴
@end

第26條:勿在分類中聲明屬性

  1. 把封裝數(shù)據(jù)所用的全部屬性都定義在主接口里。
  2. 在“class-continuation分類”之外的其他分類中,可以定義存取方法,但盡量不要定義屬性。
  3. 分類的目標(biāo)在于擴(kuò)展類的功能,而非封裝數(shù)據(jù)。
  4. 屬性所要表達(dá)的意思是:類中有數(shù)據(jù)在支持著它,屬性是用來封裝數(shù)據(jù)的。
    下面的方式,好多項(xiàng)目中都在用,但不推薦:
#import "WCCPerson.h"

@interface WCCPerson (Friendship)

@property (nonatomic, strong)NSArray *friends;

@end
#import "WCCPerson+Friendship.h"
#import <objc/runtime.h>

static const char *kFriendsPropertyKey = "kFriendsPropertyKey";

@implementation WCCPerson (Friendship)

- (NSArray *)friends{
    return objc_getAssociatedObject(self, kFriendsPropertyKey);
}

- (void)setFriends:(NSArray *)friends{
//這里聲明的內(nèi)存管理語義要和.h文件中聲明的一致就好
    objc_setAssociatedObject(self, kFriendsPropertyKey, friends, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

第27條:使用“class-continuation分類”隱藏實(shí)現(xiàn)細(xì)節(jié)

  1. 通過“class-continuation分類”向類中新增實(shí)例變量。
  2. 如果某屬性在主接口中聲明為“只讀”,而類的內(nèi)部又要用設(shè)置方法修改此屬性,那么就在“class-continuation分類”中將其擴(kuò)展為“可讀寫”。
  3. 把私有方法的原型聲明在“class-continuation分類”里面。
  4. 若想使類所遵循的協(xié)議不為人所知,則可于“class-continuation分類”中聲明。

第28條:通過協(xié)議提供匿名對(duì)象

  1. 協(xié)議可在某種程度上提供匿名類型。具體的對(duì)象類型可以淡化成遵從某協(xié)議的id 類型,協(xié)議里規(guī)定了對(duì)象所應(yīng)實(shí)現(xiàn)的方法。
  2. 使用匿名對(duì)象來隱藏類型名稱(或類名)。
  3. 如果具體類型不重要,重要的是對(duì)象能夠響應(yīng)(定義在協(xié)議里的)特定方法,那么使用匿名對(duì)象來表示。

點(diǎn)擊進(jìn)入 第五章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容