美文网首页
第六章 块(Block)与大中枢派发(Grand Central

第六章 块(Block)与大中枢派发(Grand Central

作者: 写下岁月的痕迹 | 来源:发表于2021-08-24 10:21 被阅读0次

    总结

    一、理解“块”这一概念

    1、块的基础知识

    (1)、概念:

    块用“^”符号来表示,后面跟着一对花括号,括号里面是块的实现代码。例如:

    ^{
        // Block implementation here
    }
    

    块其实就是个值,也有其相关类型,可以把块赋给变量并使用它。块类型的语法与函数指针近似。例如,无参数无返回值的块类型定义如下:

    void (^someBlock)() = ^{
            //  Block implementation here
    };
    

    因此,我们可以把块类型的语法结构写成这样子,如下:

    return_type (^block_name) (parameters)
    

    例子:

    int (^addBlock) (int a, int b) = ^(int a, int b) {
        return a + b;
    };
    

    (2)、块的内部结构

    块本身也是对象,在存放块对象的内存区域中,首个变量是指向Class对象的指针(isa),下图描述了块对象的内存布局。


    WechatIMG156.jpeg

    在内存布局中,最重要的就是invoke变量,这是个函数指针,指向块的实现代码。

    (3)、全局块、栈块及堆块

    定义块的时候,其所占的内存区域是分配在栈中的。
    若要在块定义的范围之外使用,则需给块对象发送copy消息以拷贝之,这样就把块从栈复制到堆了,拷贝后的块就可以在定义它的那个范围之外使用了。
    块也可以定义成全局的。

    2、为常用的块类型创建typedef

    为了隐藏复杂的块类型,需要使用类型定义,如:

    typedef int (^EOCSomeBlock) (BOOL flag, int value);
    EOCSomeBlock block = ^(BOOL flag, int value) {
        //Implementation
    };
    

    3、用 handler 块降低代码分散程度

    在程序里使用delegate的地方都可以使用Block来替换,其使用方法如下:

    typedef void (^EOCNetworkFetcherCompletionHandler) (NSData *data, NSError *error);
    
    @interface EOCNetworkFetcher : NSObject
    - (void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;
    @end
    

    4、用块引用其所属对象时不要出现保留环

    1、如果块所捕获的对象直接或间接地保留了块本身,那么久得当心保留环的问题。
    2、一定要找个适当的时机解除保留环。

    5、多用派发队列,少用同步锁

    1、有种简单而高效的办法可以代替同步块或锁对象,那就是使用“串行同步队列”。

    dispatch_queue_t  _syncQueue = dispatch_queue_create("com.effectiveobjectivec.syncQueue", NULL);
    - (NSString *)someString {
      __block NSString *localSomeString;
      dispatch_sync(_syncQueue, ^{
           localSomeString = _someString;
      });
      return localSomeString;
    }
    
    - (void)setSomeString:(NSString *)someString {
        dispatch_sync(_syncQueue, ^{
            _someString = someString;
        });
    }
    

    进一步优化,可以将设置实例变量的方法中所用到的块同步改成异步:dispatch_async(_syncQueue, ^{});

    相关文章

      网友评论

          本文标题:第六章 块(Block)与大中枢派发(Grand Central

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