什么是位段?
位段(bit-field)是以位為單位來定義結構體(或聯合體)中的成員變量所占的空間。含有位段的結構體稱為位段結構。
優點:采用位段結構既能夠節省空間,又方便于操作。
拓展鏈接:什么是位段?
分析
在實現委托模式時,如果協議中的方法是可選的,經常需要寫代碼來判斷某個委托對象是否能響應特定的選擇子,那么就會出現下列代碼:
if ([_delegate respondsToSelector:@selector(personDidSomething:)]) {
[_delegate personDidSomething:something];
}
但是在委托對象本身沒變的情況下,如果頻繁執行此操作的話,那么除了第一次檢測結果是有用之外,后續的檢測可能都是多余的。在這里,可以把委托對象是否能響應某個協議方法這一信息緩存起來,以優化代碼執行的效率。
案例
@class Man;
@protocol ManDelegate
@optional
- (void)man:(Man)man playGame:(NSString *) game;
- (void)man:(Man)man eatFood:(NSString *)food;
@end
我們可以使用結構體來存儲某個代理是否用respondsToSelector方法檢測過。先在Man類下聲明一個結構體:
@interface Man () {
struct {
unsigned int playGame : 1;
}_delegateFlags;
}
在上述結構體中,playGame位段占用1個二進制位,它可以表示0或1這兩個值。我們可以通過下面的方法操作上述兩個位段。
//set
_delegateFlags.playGame = 1;
//get
if (?!_delegateFlags.playGame) {}
實現緩存功能所用的代碼可以寫在delegate屬性所對應的設置方法里:
- (void)setDelegate:(id<ManDelegate>)delegate {
_delegate = delegate;
_delegateFlags.playGame = [delegate respondsToSelector:@selector(man:playGame:)];
}
這樣的話,每次調用delegate的相關方法之前,就不用檢測委托對象是否能響應給定的選擇子了,而是直接查詢結構體里的標識。
優化前
if ([_delegate respondsToSelector:@selector(man:playGame:)]) {
[_delegate man:self playGame:game];
}
優化后
if (_delegateFlags.playGame) {
[_delegate man:self playGame:game];
}
在相關代理方法需要調用多次時,這種緩存優化策略還是很有必要的。