避免Block的循環(huán)引用
什么是循環(huán)引用,什么時(shí)候發(fā)生循環(huán)引用
1 循環(huán)引用就是當(dāng)self 擁有一個(gè)block的時(shí)候,在block 又調(diào)用self的方法。形成你中有我,我中有你,誰都無法將誰釋放的困局。
self.myBlock = ^{
[self doSomething];
};
+-----------+ +-----------+
| self | | Block |
---> | | --------> | |
| retain 2 | <-------- | retain 1 |
| | | |
+-----------+ +-----------+
又或者
ClassA* objA = [[[ClassA alloc] init] autorelease];
objA.myBlock = ^{
[self doSomething];
};
self.objA = objA;
+-----------+ +-----------+ +-----------+
| self | | objA | | Block |
| | --------> | | --------> | |
| retain 1 | | retain 1 | | retain 1 |
| | | | | |
+-----------+ +-----------+ +-----------+
^ |
| |
+------------------------------------------------+
這是時(shí)官方的解釋。
大體意思就是,例如self 有一個(gè)button ,而你又要 調(diào)用 button的某個(gè)東西設(shè)置.
[self.button ^{ }]
到這步為止那就一點(diǎn)問題都沒有,但是由于某些原因,你又要在這個(gè)block里調(diào)用
self.label.text = @"I am Label";
就變成這樣了。
[self.button ^{
self.label.text = @"I am Label";
}];
//這個(gè)時(shí)候就變成這樣了。
+-----------+ +-----------+ +-----------+
| self | | button | | Block |
| | --------> | | --------> | |
| retain 1 | | retain 1 | | retain 1 |
| | | | | |
+-----------+ +-----------+ +-----------+
^ |
| |
+------------------------------------------------+
大體理解就是這樣,如果有偏差,歡迎指出。
解決方法
簡而言之就一句話的事情:
__weak typeof (self) weakSelf = self;
例如上面那個(gè)例子,只要如下即可。
__weak typeof (self) weakSelf = self;
[self.button ^{
weakSelf.label.text = @"I am Label";
}];
//這個(gè)時(shí)候就變成這樣了。
+-----------+ +-----------+ +-----------+
| self | | button | | Block |
| | --------> | | --------> | |
| retain 1 | | retain 1 | | retain 1 |
| | | | | |
+-----------+ +-----------+ +-----------+
^ |
| |
+ - - - - - - - - - - - - - - - - - - - - - - - -+
weak