block循环引用

自从 block 横空出世,它本身就封装了一段代码当做变量,Apple 导入 block 语法之后就大幅改变了撰写 Objective-C 语言的方法。
block 是Cocoa/Cocoa Touch Framework 中的匿名函式(Anonymous Functions)的实作。所谓的匿名函式,就是一段 具有物件性质的程式码,这一段程式码可以当做函式执行,另一方面,又可以当做物件传递;因为可以当做物件传递,所以可以让某段程式码变成是某个物件的某个 property,或是当做 method 或是 function 的参数传递,就是因为这种特性,造成最常使用 block 的时机,就是拿 block 实作 callback。

循环引用是指对象间相互强引用了对方,而导致双方都无法被释放。
block的循环引用,即如果我们在block中调用self,那么就产生了循环引用。
在这里插入图片描述
在这里插入图片描述

block循环引用_第1张图片

循环引用会造成APP的内存泄漏、消耗变高,使APP性能变差,用户体验不好,更坏的情况是造成APP闪退。

如何防止循环引用?
方法1 尽量不要在block中使用self,避免不了的话,我们可以使用weak(弱引用),用weak替代strong,打断循环引用!!!
方法2 block使用完成后,即设置为nil,打破循环引用!!!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码示例

1、定义

typedef void (^PersonRun)(CGFloat speed);

@interface Person : NSObject

@property (nonatomic, strong) NSString *nickName;

- (void)runWithSpeed:(CGFloat)speed;
@property (nonatomic, copy) __nullable PersonRun run;

@end

@implementation Person

- (void)runWithSpeed:(CGFloat)speed
{
    if (self.run) {
        self.run(speed);
    }
    self.run = NULL;
}

@end

2、使用,定义成属性

self.person = [[Person alloc] init];
self.person.nickName = @"devZhang";
self.person.run = ^(CGFloat speed) {
        
        // 使用weak修饰,弱引用
//        NSLog(@"1 %@", weakSelf.person.nickName);

        // 2 码源里处理
        NSLog(@"2 %@", self.person.nickName);

       // 3 调用时处理
//        self.person.run = nil;
};
[self.person runWithSpeed:100];

注意:

1 方法1 弱引用

定义weak变量__weak typeof(self) weakSelf = self;
block'里使用NSLog(@“1 %@”, weakSelf.person.nickName);`

2 方法2 block使用完成后置为nil

如在定义的位置进行设置if (self.run) { self.run(speed); } self.run = nil;
或在调用的位置进行设置self.person.run = ^(CGFloat speed) { ... self.person.run = nil;};

block属性定义@property (nonatomic, copy) __nullable PersonRun run;时,使用__nullable修改,否则设置为nil值时,会出现警告null passed to a callee that requires a non-null argument

你可能感兴趣的:(iOS,开发编码收集,iOS,内存管理,iOS,开发问题集)