美文网首页
对iOS的Block简单理解

对iOS的Block简单理解

作者: 雨天多久就 | 来源:发表于2019-11-10 18:07 被阅读0次

声明和使用Block

^操作符有两个作用:

  • 表示声明一个block变量,
  • 可以用来标识一个block定义的开始。
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
image

直接使用Block

有很多场景下,我们不需要声明block就可以直接使用。
可以直接书写block的定义作为一个参数传递给函数

    [NetWorkTool testBlock:^{
        
    }];

__block标记变量

block可以直接使用和它处于相同作用域下的变量(高级别的变量,比如全局变量不仅可以使用,还可以直接修改),但是只能使用,无法修改。
给变量加上__block标识后,就可以进行修改了。

Block 和 变量

block内的变量会有五种对待方式:

  • 全局变量和同等作用域里的静态变量 可以进行访问 (可以进行读写)
  • 传递给block的参数 可以进行访问 (可以进行读写)
  • 同等作用域下,堆栈上的变量,被捕获作为常量变量 (只可以读取值)
  • 上面一条的变量,如果加上__block,就可以进行访问 (可以进行读写)
  • 块内部的变量,其行为和正常的局部变量一样

对象 和 block变量

(这个很关键,block造成的内存泄漏问题一般都是这个原理)
当block被拷贝的时候,block内的对象变量会被强引用

  • 如果你通过引用去访问实例变量,self就会被block进行强引用
  • 如果你通过值去访问一个实例变量,这个变量会被强引用
dispatch_async(queue, ^{
    // instanceVariable is used by reference, a strong reference is made to self
    doSomethingWithObject(instanceVariable);
});

id localVariable = instanceVariable;
dispatch_async(queue, ^{
    /*
      localVariable is used by value, a strong reference is made to localVariable
      (and not to self).
    */
    doSomethingWithObject(localVariable);
});

循环引用相关例子

问题1: 下面这个例子,vc离开的时候能否正常被释放?
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    void(^MyTwoBlock)(void) = ^{
        [self view];
    };
    MyTwoBlock();
}
回答:可以正常释放。 因为MyTwoBlock虽然会对self进行强引用,但是viewDidload执行完毕后,block就释放掉了,所以没有引用环。

问题2: 下面的例子,vc离开的时候能否正常被释放?

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    void(^MyTwoBlock)(void) = ^{
        [self view];
    };
    self.kmjBlock = MyTwoBlock;
}
回答:会造成内存泄漏。因为self对MyTwoBlock有个强引用了。
问题3:属性设置成copy和strong有什么区别吗?
@property (nonatomic, strong) void(^kmjBlock)(void);//
@property (nonatomic, copy) void(^kmjBlock)(void);//
回答:没有区别。因为block是否在堆上是由系统直接完成的。如果一个block内部访问了外部的变量,就会自动被拷贝到堆上。所以这里用strong修饰和copy修饰,其实都只是增加了一个强引用。

block如何实现可以捕获外部变量以及可以在其他时机进行调用的?

大致原理是:系统先创建了一个block相关的结构体,将当前作用域下的变量(个人觉得只有局部变量需要传递)和block块的函数地址传递给这个结构体存下来,这样当block代码块要执行的时候,拿着结构体里存的信息就可以执行。
具体实现代码可以看这里:ios - block原理解读(一)

相关文章

  • 对iOS的Block简单理解

    声明和使用Block ^操作符有两个作用: 表示声明一个block变量, 可以用来标识一个block定义的开始。 ...

  • 块与GCD

    没读这本书之前,我对 block理解的成长过程; block编程对于许多初识iOS编程的人来说,很难理解和运用,我...

  • iOS - block原理解读(三)

    前言 在阅读该篇文章前,推荐阅读ios - block原理解读(一)ios - block原理解读(二) 本文解决...

  • Block浅析

    参考了网上的一些Block的文档,加上自己对Block的使用、理解,对Block做一个简单的分析。 Block是C...

  • 对iOS-Block的理解

    在OC中,所谓的block:就是一个代码块,我们可以理解为类似一个方法。 关于Block的内存管理: 都说可以把B...

  • iOS Objective-C Block底层原理

    iOS Objective-C Block底层原理 在上一篇文章中我们对Block做了简单的介绍,下面我们通过这篇...

  • 【iOS开发】一些不错的文章博客整理

    持续更新... RunLoop ibireme深入理解RunLoop Block 声明Block 组件化 iOS组...

  • 2021-06-07

    IOS block 简单的可以认为是NSObject 对象(superclass:NSBlock) block就是...

  • ios block使用

    iOS Block的使用一 .最简单的block使用******使用block的三个步骤:1.定义block变量 ...

  • Block - __block关键字的底层实现原理

    参考文档 iOS中__block 关键字的底层实现原理 你真的理解__block修饰符的原理么? iOS Bloc...

网友评论

      本文标题:对iOS的Block简单理解

      本文链接:https://www.haomeiwen.com/subject/ynjxbctx.html