首页投稿(暂停使用,暂停投稿)iOS 开发 程序员

第四章 协议与分类(EffectiveObjective-C)

2016-07-03  本文已影响73人  谁动了MyWorld

1 通过委托与数据源协议进行对象间通信

@class EOCNetworkFetcher;
@protocol  EOCNetworkFetcherDelegate<NSObject>
@optional- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailWithError:(NSError *)error;
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didUpdateProgressTo:(CGFloat)progress;
@end
@interface EOCNetworkFetcher : NSObject
@property (nonatomic, weak) id<EOCNetworkFetcherDelegate> delegate;
@end

@interfaceEOCNetworkFetcher (){
    struct {       
       unsignedint didReceiveData     : 1; 
       unsignedint didFailWithError   : 1; 
       unsignedint didUpdateProgessTo : 1;
    }_delegateFlags;
}
@end
@implementation EOCNetworkFetcher
//重写set方法,实现缓存功能所有的代码如下
//在相关方法要调用很多次时, 且要频繁通过数据协议从数据源中获取多份相互独立的数据
- (void)setDelegate:(id<EOCNetworkFetcherDelegate>)delegate{   
     _delegate = delegate;  
     _delegateFlags.didReceiveData = [delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)]; 
     _delegateFlags.didFailWithError = [delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
     _delegateFlags.didUpdateProgessTo = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}
@end

这样的话,每次调用delegate的相关方法,就不用检测委托对象是否能够响应给定的选择器了

if (_delegateFlags.didReceiveData) {
    [_delegatenetworkFetcher:selfdidReceiveData:nil]
}

2 将类的实现代码分散到便于管理的数个分类之中

类中经常容易填满各种方法,可以通过OC的"分类"机制,把类代码逻辑划入几个分区中.
注意相关类的说有属性必须放在主接口中,而不是分类中

3 总是为第三方类的分类名称加前缀

4 勿在分类中声明属性

属性是封装数据的方式,除"class-continuation"之外,其他分类都无法向类中新增实例变量.因此,他们无法把实现属性所需的实例变量合成出来,在分类中添加属性会报如下警告:

@interface EOCPerson (FriendShip)
@property (nonatomic, strong) NSArray *friends;
- (BOOL)isFriendsWith:(EOCPerson *)person;
@end

Property 'friends' requires method 'friends' to be defined - use @dynamic or provide a method implementation in this category

当然这种警告是可以消除的,通过关联对象

#import "EOCPerson+FriendShip.h"
#import <objc/runtime.h>
staticconstchar *kFriendsPropertyKey = "kFriendsPropertyKey";
@implementation EOCPerson (FriendShip)
- (NSArray *)friends{   
   return  objc_getAssociatedObject(self, kFriendsPropertyKey);
}
- (void)setFriends:(NSArray *)friends{
    objc_setAssociatedObject(self, kFriendsPropertyKey, friends, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

5 使用"class-continuation分类"隐藏实现细节

@interfaceEOCObject ()
- (void)p_privateMthod;
@end
@implementation EOCObject
- (void)p_privateMthod{
    NSError *error;
    [selfdoSomething:&error];
}
@end

6 通过协议提供匿名对象

上一篇 下一篇

猜你喜欢

热点阅读