zoukankan      html  css  js  c++  java
  • (iOS) __block和__weak认识

    果然还是对最基础的知识了解不透彻,今天看一看iOS中的两个修饰符:__block和__weak 。也是做一下温习吧。

    1、先说weak,<弱引用>

    我们知道weak的使用,比如声明一个控件属性,就会用到weak。

    看代码:

    @property(nonatomic,weak)UILabel *label;

    当然这并不是说声明控件就一定使用weak,相反的我在手动创建控件是大多数会使用strong。但如果你比较细心的话,你会发现我们使用xib时,使用的却是weak这一属性。那问题来了,我们使用strong 和 weak 的时机是何时呢?咱们接着往下看。

    从storyboard 或者xib上创建控件

     在控件放在view上的时候,已经形成了如下的引用关系,以UILabel为例:UIViewController->UIView->subView-> UILabel

    然后你为这个UILabel声明一个weak属性

    @property(nonatomic,weak) IBOOutlet UILabel * label;

    相当于xib对这个label是强引用,你声明的属性对它是弱引用。

     手动创建控件

     a). 将控件声明成strong
    @property(nonatomic,strong) UIlabel * label;

     那么你在实现这个控件时只需这样:

    _label = [[UIlabel alloc]init];
    [self.view addSubview:_label]

     

     b). 将控件声明成weak
    @property(nonatomic,weak) UIlabel * label;

     那么你在实现这个控件时需要这样:

    UIlabel *label = [[UIlabel alloc]init];
    _label = label;
    [self.view addSubview:_btn];

     

    关于block循环引用的问题

    由于block会复制外部的变量,所以如果不注意,就会造成循环引用。对于这种情况,需要将引用的一方变成weak,从而避免循环引用。
    看代码:

    BlocksViewController *blockVC = [[BlocksViewController alloc]init];
    __weak ViewController *weekSelf = self;
    /**
    * 1、使用弱引用来解决block循环引用问题
    *
    * 2、block能截取自动变量,并且是不能在block块中进行修改的(除非用 __block修饰符)这里的 weekSelf.textField.text 的值是被修改了,并且没有使用 __block修饰符。原因是因为textField是全局变量,如果定义一个局部变量,比如:定义个 “text”是不能被修改的,编译器会报错,
    */
    
    //block回调传值
    [blockVC returnValue:^(NSString *content) {
    weekSelf.textField.text = content;
    // text = content;//这里会提示错失__block;
    }];

     

    2、strong和weak的区别

    a) strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。


    b) weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。


    c)strong和copy是用来修饰强引用的属性,weak 用来修饰弱引用的属性;


    d)strong、weak 需要ARC支持才能使用,copy不需要ARC支持


    e)strong与retain功能相似;weak与assign相似,只是当对象消失后weak会自动把指针变为nil;


    3、关于__block

    先看一段代码:

    @autoreleasepool {
    __block NSInteger value = 0;
    void (^block)(void) = ^{
    value = 1;
    };
    block();
    NSLog(@"val = %ld", value);
    }

    我们现在看着可能得不出什么结论,那么,我们再看下面的代码,为了直观,我以图片的形式呈现:

    __block改变block内部变量问题一

     

    __block改变block内部变量问题二

    现在对比就明显了。

    下面总结一下:

    a) 1.__block对象在block中是可以被修改、重新赋值的。


    b)2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。


    c)3.blocks可以访问局部变量,但是不能修改。


    如果修改局部变量,需要加__block ,所以__block 是让修改外部变量的值.

     

    对于 block 外的变量引用,block 默认是将其复制到其数据结构中来实现访问的

    const-non-local-variables

    对于用 __block 修饰的外部变量引用,block 是复制其引用地址来实现访问的

    mutable-non-local-variables

    4、__block 和__weak修饰符的区别:

    1>.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

    2>.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。

    3>.__block对象可以在block中被重新赋值,__weak不可以。

     

    **链接:**

    [谈Objective-C block的实现]<http://blog.devtang.com/2013/07/28/a-look-inside-blocks/>

    [Blocks are Objective-C`s]<http://rypress.com/tutorials/objective-c/blocks>

    [iOS开发-由浅至深学习block]<http://www.cnblogs.com/luoxiaofu/p/5445327.html>

     

  • 相关阅读:
    Leetcode 126.单词接龙II
    Leetcode 125.验证回文串
    Leetcode 124.二叉树中的最大路径和
    Leetcode 123.买卖股票的最佳时机III
    Leetcode 122.买卖股票的最佳时机II
    西子凌波回复集5(网友整理版)
    西子凌波回复集4(网友整理版)
    西子凌波回复集3(网友整理版)
    K杀(逻辑-标准-规则)
    西子凌波49:2018年11月29日微博解盘提示
  • 原文地址:https://www.cnblogs.com/LQCQ-Silent/p/5914451.html
Copyright © 2011-2022 走看看