Swift3.0 -- 闭包的循环引用与OC的对比

来源:互联网 发布:上海知行生物科技传销 编辑:程序博客网 时间:2024/06/05 07:38
import UIKitclass ViewController: UIViewController {    var a: (() -> ())?            override func viewDidLoad() {        super.viewDidLoad()        //block 中如果出现 self. 要特别小心!        // "循环"引用,单方向的引用是不会产生循环引用的        // - 只是闭包对self 进行了copy        // - 同时需要self对闭包引用                //*******解除循环引用        // 方法一:用oc的方法        // 细节1:用var不用let,weak只能修饰var 不能 修饰 let        // 'weak' must be a mutable variable, because it may change at runtime        // weak可能会在运行时被修改 -> 指向的对象一旦被释放,会自动设置为nil//        weak var weakSelf = self;//        loadData {            // 细节2            // 解包有两种方式            // ? 可选解包  如果self已经被释放,不会向对象发送 view 的消息,更安全            // ! 强行解包  如果self已经被释放,强行解包会导致崩溃            // Expression implicitly coerced from 'UIView?' to Any                        /*                weakSelf?.view 只是单纯的发送消息,不参与计算                强行解包,因为需要计算,可选项不能直接参与计算            *///            print(weakSelf?.view);//        }                        //方法2 - swift的推荐方法        //[weak self] 表示 () 中的所有 self 都为弱引用//        loadData { [weak self] in//            print(self?.view as Any);//        }                // 方法3 - swift的另一种方法,知道就好,不安全        // [unowned self] 表示 () 中的所有 self 都为assign, 不会强引用,如果对象释放,指针地址依然存在        // 如果对象释放, 会出现野指针的现象        loadData { [unowned self] in            print(self.view);        }    }        func loadData(bibao: @escaping () -> ()) {        // 使用属性记录闭包 -> self 对闭包引用        a = bibao;                //异步        DispatchQueue.global().async {             print("1111");                        Thread.sleep(forTimeInterval: 2);                        DispatchQueue.main.async(execute: {                 print("2222");                bibao();            })        }            }        deinit {        print("qqqqq");    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}


与OC的对比

#import "DemoViewController.h"@interface DemoViewController ()@property (nonatomic, copy) void (^blockCallBack)();@end@implementation DemoViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    //    //解除方法1:-- __weak//    __weak typeof(self) weakSelf = self;//    [self loadData:^{//        NSLog(@"%@", weakSelf.view);//    }];        //解除方法2:-- __unsafe_unretained    //EXC_BAD_ACCESS ,坏内存访问,野指针访问    // __unsafe_unretained 同样是assign的引用(MRC中并未有weak)    // MRC中,弱引用直接用assign,不会增加引用计数,但是对象一旦被释放,会出现野指针    // ARC中,__weak相当于一个观察者,一旦发现对象被释放,会自动设置为nil,会更加安全。        //weak的效率会差一些    __unsafe_unretained typeof(self) weakSelf = self;    [self loadData:^{        NSLog(@"%@", weakSelf.view);    }];}-(void)loadData:(void (^)())block {        self.blockCallBack = block;        dispatch_async(dispatch_get_global_queue(0, 0), ^{               NSLog(@"延时操作:%@", [NSThread currentThread]);                [NSThread sleepForTimeInterval:2.0];                dispatch_async(dispatch_get_main_queue(), ^{                        block();                    });            });    }@end


0 0
原创粉丝点击