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;
浙公网安备 33010602011771号