第23條:通過委托與數(shù)據(jù)源洗衣進(jìn)行對(duì)象間通信
- 委托模式為對(duì)象提供 一套接口,使其可由此將相關(guān)事件告知其他對(duì)象。
- 將委托對(duì)象應(yīng)該支持的接口定義成協(xié)議,在協(xié)議中把可能需要處理的事件定義成方法。
- 若有必要,可實(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è)分類之中
- 使用分類機(jī)制把類的實(shí)現(xiàn)代碼劃分成易于管理的小塊。
- 將應(yīng)該視為“私有”的方法歸入名叫Private的分類中,已隱藏實(shí)現(xiàn)細(xì)節(jié)。
第25條:總是為第三方類的分類名稱加前綴
- 向第三方類中添加分類時(shí),總應(yīng)該給其名稱加上你專用的前綴。
- 向第三方類中添加分類時(shí),總應(yīng)給其中的方法名加上你專用的前綴
@interface NSString (ABC_HTTP)//分類名加前綴
- (NSString *)abc_urlEncodedString;//方法名加前綴
@end
第26條:勿在分類中聲明屬性
- 把封裝數(shù)據(jù)所用的全部屬性都定義在主接口里。
- 在“class-continuation分類”之外的其他分類中,可以定義存取方法,但盡量不要定義屬性。
- 分類的目標(biāo)在于擴(kuò)展類的功能,而非封裝數(shù)據(jù)。
- 屬性所要表達(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é)
- 通過“class-continuation分類”向類中新增實(shí)例變量。
- 如果某屬性在主接口中聲明為“只讀”,而類的內(nèi)部又要用設(shè)置方法修改此屬性,那么就在“class-continuation分類”中將其擴(kuò)展為“可讀寫”。
- 把私有方法的原型聲明在“class-continuation分類”里面。
- 若想使類所遵循的協(xié)議不為人所知,則可于“class-continuation分類”中聲明。
第28條:通過協(xié)議提供匿名對(duì)象
- 協(xié)議可在某種程度上提供匿名類型。具體的對(duì)象類型可以淡化成遵從某協(xié)議的id 類型,協(xié)議里規(guī)定了對(duì)象所應(yīng)實(shí)現(xiàn)的方法。
- 使用匿名對(duì)象來隱藏類型名稱(或類名)。
- 如果具體類型不重要,重要的是對(duì)象能夠響應(yīng)(定義在協(xié)議里的)特定方法,那么使用匿名對(duì)象來表示。