查看: 113|回复: 0

Swift与OC真正去理解Block解决轮回引用的技巧

[复制链接]
发表于 2016-8-31 23:19:06 |未经授权,严禁转载,违者必究... | |阅读模式
轮回 理解 引用 解决 技巧 swift block循环引用 oc block 循环引用 swift 调用oc block swift 调用oc 中block swift调用oc的block swift oc block oc引用swift oc引用swift报错 swift 引用 oc 枚举
媒介
本文不会具体介绍Block(闭包)利用,上也有良多具体的介绍。我们利用Block经常要留意轮回引用问题,在很早以前我只用到了__weak并不知道__strong用的有啥意义存在。后来碰到坑了才大白此中的真理!之前文章中也提到这个问题,仅仅是讲了利用层面,并没有去讲若何理解此中的事理,接下来我们来理解一下
图中的每条橙色的线都是强引用。shop指向着LRShop对象,内部myBlock指向着Block代码块,string指向着@"",最后Block代码块指向着LRShop对象
#define LRWeakSelf(type)  __weak typeof(type) weak##type = type;
LRWeakSelf(shop);
    shop.myBlock = ^{
        NSLog(@"%@",weakshop.string);
    };
    shop.myBlock();
Block外部声了然一个弱引用,在内部利用就不会造成轮回引用,所以假如block代码块的内部,利用了外面声明的的弱引用weakshop对象(也就是shop.myBlock代码块内部利用了NSLog(@"%@",weakshop.string);),block代码块的内部会主动发生一个弱引用,引用着shop对象!我们继续来看下内存图:
总结:Block内部利用外部的一个对象,假如外部对象是强引用那么内部会主动生成一个强引用,引用着外部对象
。假如外部对象是弱引用那么内部会主动生成一个弱引用,引用着外部对象。假如仍是有点苍茫我们最后在举一个例子:
上面的代码会不会造成轮回引用呢?谜底是不会的,起首self.myName是ViewController节制器的一个属性,Block内部利用外部的self.myName,外部的self.myName是强引用那么内部会主动生成一个强引用引用着self.myName。Block内部强引用self.myName,可是self.myName没有强引用Block!说白了就是粉丝与明星的关系,粉丝(Block)片面追求明星(self.myName),可是随便粉丝怎么片面的追求,明星都不搭理粉丝!
我们先看看下面代码:
概况来看外部一个弱引用,内部一个强引用那不是跟没写一样么?我们要理解一个问题LRStrongSelf(shop)是Block内部的强引用,而不是外部强引用
。所以Block内部声明的强引用不管怎么拜候都是不会干扰外部的对象,也不会主动发生一个强引用。所以没有轮回引用,也能输出shop.string看着跟之前讲的仅仅利用__weak没什么区别,那我们在来看看下面的代码:
//弱引用
LRWeakSelf(shop);
    shop.myBlock = ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@",weakshop.string);
        });
    };
    shop.myBlock();

2353624-0a71a7b33f4010c4.png

2353624-0a71a7b33f4010c4.png

假如LRWeakSelf(shop);与LRStrongSelf(shop);一路利用输出的shop.string有值,对象也销毁了:
那这又是什么原因呢?我们继续画个内存图来看看:
额~ 这图有点乱啊,那就来一步一步阐发,阐发完之后上面所有的问题就会迎面而解!
上面6条是若何建立的,下面是若何释放的:
在Swift中解决闭包轮回引用有三种法子我们来看看:
    let shop : LRShop = LRShop()
    weak var weakShop = shop
    shop.myBlock = {(str : String) -> () in
        weakShop?.string = str
        print((weakShop?.string)!)
    }
    shop.myBlock!(str: "哈喽,你好!")
  • 2.[unowned shop]体例解决轮回引用,在日常平凡开辟中我们不消这个方式,这个方式是很危险的!

        let shop : LRShop = LRShop()   
        shop.myBlock = {[unowned shop] (str : String) -> () in
             shop.string = str
             print(shop.string!)
         }
         shop.myBlock!(str: "哈喽,你好!")
  • 3.[weak self]体例解决轮回引用,在日常平凡开辟中我们经常用这个方式,这个体例只是一种简洁的写法!

        let shop : LRShop = LRShop()
        shop.myBlock = {[weak shop] (str : String) -> () in
                shop?.string = str
                print((shop?.string)!)
        }
        shop.myBlock!(str: "哈喽,你好!")
    输出成果都能解决轮回引用问题,下图deinit相当OC中的dealloc方式:
    那我们已经知道Swift顶用weak也能解决轮回引用,那么可不成以weak与strong一路利用呢?我找了没有strong这个要害字,那我们该若何解决下面延迟2秒后在执行使命的问题呢:
    我感觉既然没有strong那必定会有其他法子来解决这个问题,既然只贫乏一个强引用,那我就声明一个强引用给他用:
    上面代码就是我在闭包内部声明的一个strongShop强引用,具体代码如下:
    不管在OC中仍是Swift中我们都解决了Block(闭包)中若何优雅的解决轮回引用问题,而且也领会了造成轮回引用的内存表示形式
    。上面在Swift解决轮回引用的问题,有更好的法子还请年夜神多多指教,假如有错误的处所帮手改正,很是感激!
  • 返回顶部快速回复上一主题下一主题返回列表

    声远论坛|联系电话:0537-2311005|Archiver|手机版|小黑屋|Sitemap|声远网 |网站地图|网站地图

    鲁公网安备 37089702000485号 | 鲁ICP备 18028751号 | 互联网药品信息服务资格证:(鲁)-经营性-2022-0209 | 增值电信业务经营许可证:鲁B2-20230761号 | (鲁)职介证字[223]:第08120014号

    中国互联网违法和不良信息举报中心 | 山东省互联网违法和不良信息举报中心 | 人工智能生成合成内容标识办法

    GMT+8, 2026-5-5 05:07, Processed in 0.083709 second(s), 39 queries , Gzip On, APCu On.

    Powered by Discuz! X3.5© 2001-2026 SYUAN.COM

    快速回复 返回顶部 返回列表