在block中常常會(huì)用到weakSelf和strong來(lái)處理block的產(chǎn)生循環(huán)引用的問(wèn)題。
使用情況
- 直接在 block 里面使用關(guān)鍵詞 self
- 在 block 外定義一個(gè) __weak 的 引用到 self,并且在 block 里面使用這個(gè)弱引用
- 在 block 外定義一個(gè) __weak 的 引用到 self,并在在 block 內(nèi)部通過(guò)這個(gè)弱引用定義一個(gè) __strong 的引用。
直接在 block 里面使用關(guān)鍵詞 self
當(dāng)block并沒(méi)有被self對(duì)象所引用時(shí),一般可以直接使用self,例如:
dispatch_block_t completionBlock2 = ^(){
NSLog(@"complete");NSLog(@"%@", self);
};
[self presentViewController:myController
animated:YES
completion:completionBlock2];
使用weakself
當(dāng)block對(duì)象被self持有時(shí),一定要使用weakself避免循環(huán)引用。
__weak typeof(self) weakSelf = self;
self.completionHandler = ^{
NSLog(@"%@", weakSelf);
};
MyViewController *myController = [[MyViewController alloc] init...];
[self presentViewController:myController
animated:YES
completion:self.completionHandler];
使用__strong
當(dāng)block中執(zhí)行多個(gè)self的方法時(shí),推薦在block中使用strongSelf,這樣更嚴(yán)謹(jǐn)和安全,因?yàn)槿绻鹷eakSelf有可能在一些方法中被釋放導(dǎo)致后續(xù)方法無(wú)法執(zhí)行。
__weak typeof(self) weakSelf = self;
myObj.myBlock = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething]; // strongSelf != nil
// preemption, strongSelf still not nil(搶占的時(shí)候,strongSelf 還是非 nil 的)
[strongSelf doSomethingElse]; // strongSelf != nil
}
else {
// Probably nothing...
return;
}
};
總結(jié)
一般來(lái)說(shuō):如果block不是屬性則使用self,是屬性但block中調(diào)用單個(gè)self的方法時(shí)用weakSelf,多個(gè)方法用strongSelf
簡(jiǎn)單處理weakself和strongSelf
__weak __typeof(self) weakSelf = self;
__strong __typeof(weakSelf) strongSelf = weakSelf;
建議把這兩段代碼添加到xcode snippet library中。
添加方式:直接把代碼行分別拖入,重新命名snippet,設(shè)置title和complete shortcut(快捷鍵),類(lèi)型選擇code expresssion。建議title和shortcut都使用weakify和strongify
例子
__weak __typeof(self) weakSelf = self;
[self executeBlock:^(NSData *data, NSError *error) {
[weakSelf doSomethingWithData:data];
}];
//不要這樣
[self executeBlock:^(NSData *data, NSError *error) {
[self doSomethingWithData:data];
}];
多個(gè)語(yǔ)句的例子:
__weak __typeof(self)weakSelf = self;
[self executeBlock:^(NSData *data, NSError *error) {
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomethingWithData:data];
[strongSelf doSomethingWithData:data];
}
}];
//不要這樣:
__weak __typeof(self)weakSelf = self;
[self executeBlock:^(NSData *data, NSError *error) {
[weakSelf doSomethingWithData:data];
[weakSelf doSomethingWithData:data];
}];
定義宏@weakify和@strongify處理
待更新,還沒(méi)研究清楚實(shí)現(xiàn)方式.