美文网首页
Block总结

Block总结

作者: Chris脑 | 来源:发表于2017-02-22 10:52 被阅读0次

    BLOCK

    block的描述: 他是类似函数指针的一个代码块的内联封装, 他可以将一个函数体作为对象传递

    block的本质: 对象

    block的效率: 高于函数调用


    声明一个block

               返回值 (^名称)(以”逗号”分割的参数), 参数部分可以不写参数名只写类型

    范例:

                  void  (^myFirstBlock)( int a, NSString *s, UIButton *button )

                BOOL (^mySecondBlock)(void)

        NSString * (^myThirdBlock)(CGFloat, float)

    定义一个block

             ^可省略的返回值(以”逗号”分割的参数){代码块}

    范例:

            ^void(int a){NSLog(@"一个int参数, 无返回值的block"); } 

            ^{ NSLog(@"一个无参数,无返回值的block"); }                

            ^int(int a, int b){ NSLog( @"一个两个int参数, 返回两个数相加的block, 结果%d", a + b ); return a + b; }

    block作为函数参数

             block作为参数, 参数名后缀, 类型格式为: ( 返回值(^)(参数) )block名 

    范例:

    - (void)test:(int(^)(int))paramBlock

    {

            NSLog( @"打印block返回结果:%d", paramBlock(10));

    }

     block作为参数的函数调用:

             将block定义部分或将block对象传入函数调用的参数部分

    范例:

    [self test:^(int a){

            return a * a;

    }];

    __block:

    block只能只读的访问局部变量, 若需要修改局部变量, 需要通过__block修饰该变量, 该修饰符会使block自动复制该对象的指针,即指针拷贝, 当对该对象执行写操作时, 其实就是操作其指针指向的对象进行操作.

    若不加该修饰符, block仅自动复制需要访问的局部变量的值副本(值拷贝), 因此只能进行只读操作.

    __weak:

    使用block特别要注意的一点就是防止循环引用的发生, block作为一个对象被持有者持有,若block内部也持有该持有者将会导致循环引用,导致相互持有, 永远无法销毁彼此的内存问题, 若不能规避该问题, 则需要通过使用__weak修饰 block要访问的持有者变量, 防止循环引用的发生. 尤其是block所在的self.

    __strong

    该修饰符在block内的主要作用是防止__weak修饰的指针在block运行期间被外部销毁, 导致block无法顺利完成原定功能. 所以当访问的外部变量用__weak修饰时, block内部最好再有一个__strong修饰的同类型指针指向__weak指针, 这样就可以确保, 在block内部的这个指针可以运行完成. 随着block运行完成, __strong修饰的指针也将自动销毁, 进而__weak指针也会自动置nil.

    block外部变量访问

    block可以访问和修改全局变量

    block只能只读的访问局部变量(值传递, block内部复制了一个副本), 若加了__block修饰, 就改为引用传递,可修改局部变量

    block底层浅谈

    block本身包含一个结构体

    struct __block_impl

    {

    void *isa;

    int Flags;

    int Reserved;

    void *FuncPtr;

    }

    block分为三种类型, __block_impl的isa指针负责标记block类型

    _NSConcreteGlobalBlock: 全局静态block, 当block内不访问任何外部变量, 或者访问的是全局作用域,成员变量的, 属于该类型, 内存管理方式和函数一致

    _NSConcreteStackBlock 栈block, 由系统管理内存, 函数返回时销毁, 访问的外部变量由block从栈上copy到堆上, 保证了作用域结束后, block仍然可以访问

    _NSConcreteMallocBlock 堆block, 由开发者控制, 引用计数为0时销毁

    block几种自身copy的情况, 若触发一下情况, block将自动拷贝自身到堆中, 确保自身作用域内的变量的生命周期更长久

    1.显式执行copy, [block copy];

    2.block作为返回值的时候

    3.block被赋值给__strong类型的对象或者block的内部变量时

    4.block作为参数传入带有usingBlock的CocoaFramework方法

    5. block作为参数传入GCD的API时

    其他:

    __typeof, __typeof__, typeof 这三个关键字实现了一个相同的功能, 获取参数的类型名称并返回

    UIViewController *vc;

    __typeof(vc) vc2;

    这样就可以在不知道vc指针类型的情况下, 再声明一个同类型的vc2

    相关文章

      网友评论

          本文标题:Block总结

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