8.iOS开发之block

block简介

block(闭包)的本质是对象,是带有自动变量(局部变量)的匿名函数。

block与变量

值拷贝 会自动生成相应的属性来捕获外界变量,外部局部变量的变化不会影响它的的状态,block内部不能修改变量的值。

使用__block修饰符可以修改自动变量的值,是跟局部static变量一样指针传递

全局变量则是直接访问。

对于捕获ObjC对象,不同于基本类型,Block内部访问了对象类型的auto对象时,如果Block是在栈上,将不会对auto对象产生强引用当Block被拷贝到堆上,Block会调_Block_object_assign函数,根据auto对象的修饰符做出相应的操作;如果Block从堆上移除,会调用block内部的dispose函数,内部会调用_Block_object_dispose函数,这个函数会自动释放引用的auto对象。

解决block的循环引用

1.使用最简单的weak关键字修饰 

(会遇到在block中self还需要使用然而被释放)

可在block作用域内对weakSelf进行strong修饰的临时变量 weak-strong-dance强弱共舞

self.name = @"name";

    __weaktypeof(self) weakSelf =self;

    self.block= ^{

        __strongtypeof(weakSelf) strongSelf = weakSelf;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSLog(@"name:%@",strongSelf.name);

        });

    }

2.用__block修饰中间者变量使用,并在block中置为nil

 self.name = @"name";     __block ViewController *vc = self;     self.block = ^{         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{             NSLog(@"name:%@",vc.name);             vc = nil;         });     };

3.使用传参把self传入

self.name = @"name";     self.block = ^(ViewController *vc){         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{             NSLog(@"name:%@",vc.name);         });     };    

self.block(self);

Block与内存管理

根据Block在内存中的位置分为三种类型:

NSGlobalBlock是位于全局区的block,它是设置在程序的数据区域(.data区)中。

NSStackBlock是位于栈区,超出变量作用域,栈上的Block以及  __block变量都被销毁。

NSMallocBlock是位于堆区,在变量作用域结束时不受影响。

Block的复制

在全局block调用copy什么也不做

在栈上调用copy那么复制到堆上

在堆上调用block 引用计数增加

Block从栈中复制到堆的几种情况

调用Block的copy实例方法时

Block作为函数返回值返回时

在带有usingBlock的Cocoa方法或者GCD的API中传递Block时候

将block赋给带有__strong修饰符的id类型或者Block类型时

Block的底层原理

研究工具:clang

block结构体成员:

isa,指向所属类的指针,也就是block的类型

Flags,标志变量,在实现block的内部操作时会用到

Reserved,保留变量

FuncPtr,block执行时调用的函数指针

包含了isa指针(包含isa指针的皆为对象),也就是说block也是一个对象(runtime里面,对象和类都是用结构体表示)。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类...
    司马DE晴空阅读 1,439评论 0 7
  • 设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的...
    iOS菜鸟大大阅读 803评论 0 1
  • 所有的Block里面的self必须要weak一下? 很显然答案不都是,有些情况下是可以直接使用self的,比如调用...
    恋空K阅读 778评论 0 3
  • 把网上的一些结合自己面试时遇到的面试题总结了一下,以后有新的还会再加进来。 1. OC 的理解与特性 OC 作为一...
    AlaricMurray阅读 2,652评论 0 20
  • Block概要 Block:带有自动变量的匿名函数。 匿名函数:没有函数名的函数,一对{}包裹的内容是匿名函数的作...
    zweic阅读 548评论 0 2

友情链接更多精彩内容