0%

在用delegate回调数据时,避免避免持续调用 [_delegate respondsToSelector:@selector(someThingFunction)

在用delegate回调数据时,避免避免持续调用 [_delegate respondsToSelector:@selector(someThingFunction)

GCNetworkFetcher.h

定义protocol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <Foundation/Foundation.h>
@class GCNetworkFetcher;

@protocol GCNetworkFetcherDelegate <NSObject>

@optional
- (void)networkFetcher:(GCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
- (void)networkFetcher:(GCNetworkFetcher *)fetcher didFaileWithError:(NSError *)error;
- (void)networkFetcher:(GCNetworkFetcher *)fetcher didUpdateProgressTo:(float)progress;

@end

@interface GCNetworkFetcher : NSObject

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

@end

GCNetworkFetcher.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#import "GCNetworkFetcher.h"

@interface GCNetworkFetcher () {
//用位段的数据类型缓存方法的响应能力,避免每次回调数据的时候都去检测一下 避免持续调用 if( [_delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)]) {}
//用结构体来缓存委托对象是否能响应特定的选择器
struct {
unsigned int didReceivedData : 1;
unsigned int didFaileWithError : 1;
unsigned int didUpdateProgressTo : 1;
}_delegateFlags;
}

@end

@implementation GCNetworkFetcher

// 实现缓存功能所有的代码可以写在delegate属性所对应的设置方法里
- (void)setDelegate:(id<GCNetworkFetcherDelegate>)delegate {
_delegate = delegate;
_delegateFlags.didReceivedData = [delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
_delegateFlags.didFaileWithError = [delegate respondsToSelector:@selector(networkFetcher:didFaileWithError:)];
_delegateFlags.didUpdateProgressTo = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}

- (void)getData:(NSData *)data {
if (_delegateFlags.didReceivedData) {
[_delegate networkFetcher:self didReceiveData:data];
}
}

- (void)setError:(NSError *)error {
if (_delegateFlags.didFaileWithError) {
[_delegate networkFetcher:self didFaileWithError:error];
}
}

- (void)progress:(float)progress {
if (_delegateFlags.didUpdateProgressTo) {
[_delegate networkFetcher:self didUpdateProgressTo:progress];
}
}