oc踩过的一些循环引用坑
1、注册、移除Notification
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"test" object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"test" object:nil];
}
就是在页面出现的时候注册通知,页面消失时移除通知。你这边可要注意了,一定要成双成对出现,通过指定的 name 移除通知,如果你只在viewWillAppear 中 addObserver没有在viewWillDisappear 中 removeObserver那么当消息发生的时候,你的方法会被调用多次。
2、在block中调用其它方法
改前:
__weak typeof(self)weakself = self;
[[BluetoothUtil sharedInstance] simpleGetBLEStateWithBlock:^(NSString *stateString) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakself BLEStartScan];
});
}];
- (void)BLEStartScan {
__weak typeof(self) weakSelf = self;
}
block中调用self方法时需要把weaksekf也传递到方法中
改后:
__weak typeof(self)weakself = self;
[[BluetoothUtil sharedInstance] simpleGetBLEStateWithBlock:^(NSString *stateString) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakself BLEStartScan:weakself];
});
}];
- (void)BLEStartScan:(BindDeviceVC *)uself {
__weak typeof(self) weakSelf = uself;
}
3、在block中不能自己引用自己
[self.bridge registerHandler:@"unKnowTypeToQuestion" handler:^(id data, WVJBResponseCallback responseCallback) {
dispatch_async(dispatch_get_main_queue(), ^{
[WKWebVC showWithContro:self withUrlStr:homeUrl withTitle:title];
});
}];
在block中不能自己引用自己,所以block中WKWebVC需要改为HJWebVC(随意一个别的);
weakself问题,不能使用self
改后:
[self.bridge registerHandler:@"unKnowTypeToQuestion" handler:^(id data, WVJBResponseCallback responseCallback) {
dispatch_async(dispatch_get_main_queue(), ^{
[HJWebVC showWithContro:weakself withUrlStr:homeUrl withTitle:title];
});
}];
4、__weak和__block
在cellForRowAtIndexPath中:
改前:
__block CommentInBelieveCell *cellBlock = cell;
cell.zanBlock = ^{
};
__weak使用有问题
__weak和__block
__weak 主要用于防止block中的循环引用
__block用于修饰某些block内部将要修改的外部变量
改后:
_weak CommentInBelieveCell *cellBlock = cell;
cell.zanBlock = ^{
};
5、cellForItemAtIndexPath中block中使用cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
cell.buttonBlock = ^{
[collectionView reloadData];
};
}
其中cell和collectionView循环引用
改后:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
__weak typeof(self)weakSelf = self;
cell.buttonBlock = ^{
[weakSelf.collectionView reloadData];
};
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
cell.selectBlock = ^{
[tableView reloadData];
};
}
其中cell和tableView循环引用
改后:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
__weak typeof(self)weakSelf = self;
cell.selectBlock = ^{
[weakSelf.tableView reloadData];
};
}
6、block中使用项目中自定义的log
#define STLog(...) NSLog(@"%s(%p) %@", __PRETTY_FUNCTION__, self, [NSString stringWithFormat:__VA_ARGS__])
block和self循环调用
block中不使用STLog,必须使用观察数据的话使用NSLog
7、AFNetworking中,manage接收到请求结果后需要
__weak typeof(manager) weakManager = manager;
[weakManager invalidateSessionCancelingTasks:YES resetSession:YES];