IOS针对block块使用ARC回收问题

假设有一个块定义如下:(注:block属性要定义成copy形式,不能为strong)

1 typedef void(^AnimatedViewBlock)(CGContextRef context, CGRect rect, CFTimeInterval totalTime, CFTimeInterval dateTime);
2 
3 @property (copy, nonatomic) AnimatedViewBlock block;

 

初始化如下:

1 self.block = ^(CGContextRef context, CGRect rect, CFTimeInterval totalTime, CFTimeInterval deltaTime) {
2 
3         NSLog(@"totalTime %f, deltaTime %f", totalTime, deltaTime);
4 
5             CGPoint textPoint = CGPointMake((rect.size.width - textSize.width) / 2, (rect.size.height - textSize.height) / 2);
6 
7             [self.artisName drawAtPoint:textPoint withFont:font];
8 
9     };

 

当执行这个块时,将不能回收这个ViewController

一种方案是在 block 内部不要使用 self。那意味着你不能 调用任何属性,实例变量,或者来自 block 的方法。局部变量可以。 

代码修改如下:

 1 NSString *text = self.artisName;
 2 
 3 self.block = ^(CGContextRef context, CGRect rect, CFTimeInterval totalTime, CFTimeInterval deltaTime) {
 4 
 5         NSLog(@"totalTime %f, deltaTime %f", totalTime, deltaTime);
 6 
 7             CGPoint textPoint = CGPointMake((rect.size.width - textSize.width) / 2, (rect.size.height - textSize.height) / 2);
 8 
 9             [text drawAtPoint:textPoint withFont:font];
10 
11     };

另一种方案是,如果你真的想要在block中调用self,那就把self转换成一个局部的弱引用对象

 1 __weak DetailViewController *weakSelf = self;
 2     
 3     self.block = ^(CGContextRef context, CGRect rect, CFTimeInterval totalTime, CFTimeInterval deltaTime) {
 4         NSLog(@"totalTime %f, deltaTime %f", totalTime, deltaTime);
 5         
 6         DetailViewController *strongSelf = weakSelf;
 7 
 8             CGPoint textPoint = CGPointMake((rect.size.width - textSize.width) / 2, (rect.size.height - textSize.height) / 2);
 9             [strongSelf.artisName drawAtPoint:textPoint withFont:font];
10     };

这样就可以正常回收了

 

CF框架与OBC切换需要先有一个中间变量赋值才行

1 CGColorRef cgColor1 = [[UIColor alloc] initWithRed:1 green:0 blue:0 alpha:1].CGColor;
2 CGColorRef cgColor2 = [[UIColor alloc] initWithRed:0 green:1 blue:0 alpha:1].CGColor;
3 CGColorRef cgColor3 = [[UIColor alloc] initWithRed:0 green:0 blue:1 alpha:1].CGColor;
4 NSArray *colors = [NSArray arrayWithObjects:(__bridge id)cgColor1, (__bridge id)cgColor2, 
5 (__bridge id)cgColor3, nil];

上面的代码会引起崩溃,原因很简单,我们创建了一个UIColor 对象不是 autorelease,的而是被保留计数的(因为我们调用了 alloc+init)。一旦没有强引用指针指向这个对象,应用就会崩溃。因为一个 CGColorRef 不是一个 Object-c 对象,cgColor1 变量没有资格作为一个强引用指针。新的 UIColor 对象直接被释放在它被创建的时候,并且 cgColor1 指针指向了垃圾内存。,改为如下:

1 CGColorRef cgColor1 = [UIColor colorWithRed:1 green:0 blue:0 alpha:1].CGColor;
2 UIColor color2 = [UIColor alloc] initWithRed:0 green:1 blue:0 alpha:1];
3 CGColorRef cgColor2 = color2.CGColor;

 

posted on 2013-11-13 11:06  低调点  阅读(142)  评论(0)    收藏  举报

导航