Fork me on GitHub

iOS开发之@weakify, @strongify

为什么在使用Block时需要注意使用 @weakify@strongify

不使用 @weakify

我们在使用MJRefresh时如果不使用@weakify且如下编写代码

1
2
3
4
5
6
7
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 这里使用了 self 没有使用__weak
[self.tableView.mj_header endRefreshing];
[self.tableView reloadData];
});
}];

可以使用腾讯微信读书开源的MLeaksFinder很容易检测到内存泄露



不使用 @strongify

下面举一个不使用 @strongify 会出现的问题,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__weak typeof(self) wself = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
if (self) {
sleep(2);
NSLog(@"%@", @[wself]);
}
});
});

dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(2);
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
});

会直接崩溃,而且我们这里做了判空处理。



总结

由上面的问题可见在使用Block时注意使用@weakify@strongify 是如此的重要,那么上面的代码安全的方式应该是如下代码.

1
2
3
4
5
6
7
8
9
10
__weak typeof(self) wself = self;
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong typeof(wself) self = wself;
if (self) {
[self.tableView.mj_header endRefreshing];
[self.tableView reloadData];
}
});
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
__weak typeof(self) wself = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
__strong typeof(wself) self = wself;
if (self) {
sleep(2);
NSLog(@"%@", @[self]);
}
});
});

dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(2);
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(wself) self = wself;
if (self) {
[self.navigationController popViewControllerAnimated:YES];
}
});
});

使用我们在使用Block如果使用了self而且可能有相互引用的情况,那么应该注意 @weakify@strongify 以及 必要的判空操作

- END -
关注微信公众号,发现更多精彩

文章作者:梁大红

特别声明:若无特殊声明均为原创,转载请注明,侵权请联系

版权声明:署名-非商业性使用-禁止演绎 4.0 国际