《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个方法》

《Effective Objective-C 2.0编写高质量i

2019-01-28  本文已影响0人  Mr_WangZz

OC中两项重要的语言特性:

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

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

如果是方法是可选的(optional),在委托类中,需要先执行判断(responseToSelector)操作。

if ([_delegate responseToSelector:@selector(xxxxx)]) {
    [_delegate xxxxx];
}
完整的例子:
//
//  EOCNetworkFetcher.h
//

#import <Foundation/Foundation.h>

@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:(float)progress;

@end

@interface EOCNetworkFetcher : NSObject

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

- (void)requestWithParams:(id)params url:(NSURL *)url;


@end
/*******************************************/
/*******************************************/
//
//  EOCNetworkFetcher.m
//

#import "EOCNetworkFetcher.h"

@interface EOCNetworkFetcher (){
    /**
    这个结构体,用来缓存委托对象是否能响应特定的选择子
    2^1 = 2,表示0 和 1 两个数。
    */
    struct {
        unsigned int didReceiveData: 1;
        unsigned int didFailWithError: 1;
        unsigned int didUpdateProgressTo: 1;
    } _delegateFlags;
}
@end

@implementation EOCNetworkFetcher {}

- (void)setDelegate:(id<EOCNetworkFetcherDelegate>)delegate {
    
    _delegate = delegate;
    
    /* 优化代码执行速度
     这样就不用每次在实现要被代理的方法前,每次执行检查了。只要检查一次就好。因为在设置代理时就已经确定了。
     */
    _delegateFlags.didReceiveData = [delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
    _delegateFlags.didFailWithError = [delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
    _delegateFlags.didUpdateProgressTo = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
    
}

- (void)requestWithParams:(id)params url:(NSURL *)url {
    
    if (_delegateFlags.didReceiveData) {
        [_delegate networkFetcher:self didReceiveData:[NSData new]];
    }
    
    if (_delegateFlags.didFailWithError) {
        [_delegate networkFetcher:self didFailWithError:[NSError new]];
    }
    
    if (_delegateFlags.didUpdateProgressTo) {
        [_delegate networkFetcher:self didUpdateProgressTo:1.0f];
    }
}

@end

要点

在结构体中,
fileA 位段将占用8个二进制位,0~255;
fileB 位段将占用4个二进制位,0~16;
fileC 位段将占用2个二进制位,0~4;
fileD 位段将占用1个二进制位,0~1;

struct file {
    unsigned int fileA: 8;
    unsigned int fileB: 4;
    unsigned int fileC: 2;
    unsigned int fileD: 1;
} ;

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

要点

将类代码打散到分类中,便于调试

  1. 调试会出现分类名称,如-[EOCPerson(FriendShip) addFriend:]
  2. 方便查看,可以给类进行“瘦身”。

25. 总是为第三方类的分类名称加上前缀

@interface NSString (WZZ_HTTP)

- (NSString *)wzz_doSomeThing1;

- (NSString *)wzz_doSomeThing2;

@end
要点总结

26. 勿在分类中声明属性

属性,是用来封装数据的。

要点

27. 使用 “class-continuation” 分类实现隐藏细节

@interface EOCPerson ()

@end

//或
@implementation EOCPerson

@end
要点
//.h 中
@property (nonatomic, copy, readOnly) NSString *name;

//.m 中
@property (nonatomic, copy, readWrite) NSString *name;
//.m
@interface EOCPerson ()
- (void)p_privateMethod;//私有方法
@end
//.m
@interface EOCPerson() <EOCSecretDelegate>
@end

28. 通过协议提供匿名对象

要点
- (id<EOCSecretProtocol>)doSomeThing;

系列文章

上一篇下一篇

猜你喜欢

热点阅读