什么是循环引用?
循环引用:是指多个对象相互引用,导致内存无法释放,从而导致内存泄露。
循环引用的四种情况?
- 父类与子类
- Block
- Delegate
- NSTime
1、父类与子类
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TestTableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:@"UITableViewCellIden" forIndexPath:indexPath];
cell.tableView = tableView;
return cell;
}
以下代码会引起循环引用
@interface TestTableViewCell : UITableViewCell
@property (nonatomic, strong) UITableView *tableView;
@end
原因
因为tableView 的
strong
属性特质,使得子类持有父类,应该使用weak
解决方案
@interface TestTableViewCell : UITableViewCell
@property (nonatomic, weak) UITableView *tableView;
@end
2、Block
typedef void (^TestCircleBlock)();
@property (nonatomic, copy) TestCircleBlock testCircleBlock;
if (self.testCircleBlock) {
// 具体实现
self.testCircleBlock();
}
以下代码会引起循环引用
self.testObject.testCircleBlock = ^{
[self doSomething];
};
原因
该类将block作为自己的属性变量并持有,而该类在block的方法体里面又使用了该类本身
解决方案
__weak typeof(self) weakSelf = self;
self.testObject.testCircleBlock = ^{
__strong typeof (weakSelf) strongSelf = weakSelf;
[strongSelf doSomething];
};
3、Delegate
以下代码可能会引起循环引用
@property (nonatomic, strong) id <TestDelegate> delegate;
解决方案
@property (nonatomic, weak) id <TestDelegate> delegate;
4、NSTimer
以下代码可能会造成循环引用
#import "FirstViewController.h"
@interface FirstViewController ()
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(testTimerDeallo) userInfo:nil repeats:YES];
}
/** 方法一直执行 */
-(void)testTimerDeallo{
NSLog(@"-----");
}
/** 开启定时器以后控制器不能被销毁,此方法不会被调用 */
-(void)dealloc{
NSLog(@"First");
// [self.timer invalidate];
}
解决方案
//在进入界面时创建
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//[self.timer setFireDate:[NSDate distantPast]];
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(testTimerDeallo) userInfo:nil repeats:YES];
}
//在界面即将消失时销毁
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.timer invalidate];
}
网友评论