• iOS Block原理简析


    • Block的语法

      Block是iOS闭包的实现方式,能够获取局部变量的匿名函数。

      Block的OC声明

      返回值类型 (^Block变量名字)(参数列表) = (参数列表){};

      例子  

            int (^add)(int a,int b) = ^(int a, int b)
            {
                return a + b;
            };
            
            int sum = add(1,4);
            NSLog(@"sum = %d",sum);
            
            NSString* (^getFullName)(NSString *first,NSString *last) = ^(NSString *first,NSString *last)
            {
                return [NSString stringWithFormat:@"%@%@",first,last];
            };
            NSString *name = getFullName(@"",@"");
            NSLog(@"name = %@",name);
    • Block使用

      保存局部代码块

            //声明实现
            void (^sayHello)() = ^()
            {
                NSLog(@"hello world");
            };
            //调用
            sayHello();

      作为一般的数据类型

      使用block的时候为了方便,一般都会使用关键字typedef

    typedef void (^someOne)(int age,NSString *name); 
    someOne same = ^(int age,NSString *name)
     {
            NSLog(@"age = %d.name = %@",age,name);
     };
            
     same(19,@"same");
    //作为参数使用
    -(void)getSomeOne:(someOne)some;
    
    - (void)getSomeOne:(someOne)some
    {
        if (some) {
            some(20,@"lisi");
        }
    }
    
    BlockMode *mode = [[BlockMode alloc]init];
    [mode getSomeOne:^(int age, NSString *name) {
          NSLog(@"age = %d.name = %@",age,name);
    }];

    Block和函数的区别:1.声明方式不一样;2.block可以作为参数或者普通变量使用。

    •  Block底层实现原理

      在终端中cd命令移动到main.m所在的目录,然后使用命令,clang -rewrite-objc main.m,生成一个cpp的源文件。这个源文件的最后是我们main函数的实现。


    typedef void (*someOne)(int age,NSString *name); struct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0* Desc; __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) { impl.isa = &_NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc; } }; static int __main_block_func_0(struct __main_block_impl_0 *__cself, int a, int b) { return a + b; } static struct __main_block_desc_0 { size_t reserved; size_t Block_size; } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)}; int main(int argc, const char * argv[]) { /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; int (*add)(int a,int b) = ((int (*)(int, int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA)); int sum = ((int (*)(__block_impl *, int, int))((__block_impl *)add)->FuncPtr)((__block_impl *)add, 10, 20); } return 0; }

    这里要理解几个结构体。

    struct __block_impl {
      void *isa;
      int Flags;
      int Reserved;
      void *FuncPtr;
    };
    1.  __block_impl个人理解为block的基类,类似NSObject。
    2. __main_block_impl_0:可以理解为block变量。一个block对象包含一个__block_impl,一个描述__main_block_desc_0。
    3. __main_block_func_0:block代码块的实现。
    4. __main_block_desc_0:block的描述, Block_size;

     如果需要在block中修改局部变量,需要使用__block关键字。那么为什么加了这个之后就可以修改呢,继续看源代码。

     

     看看加了__block之后会有什么变化

    这就是为什么,加了__block之后,对变量进行修改,就可以。类似函数传参的传值和传引用。

    最后有点疑问如下:

            __block NSString *name = @"lise";
            void (^getName)() = ^()
            {
                NSLog(@"name = %@",name);
            };
            name = @"ali";
            getName();//假如这个block块永远没有执行,name什么时候释放。

    希望明白的同学不吝赐教。

  • 相关阅读:
    Python学习 Day 1-简介 安装 Hello world
    R Programming week2 Functions and Scoping Rules
    R in action读书笔记(6)-第七章:基本统计分析(中)
    R in action读书笔记(5)-第七章:基本统计分析
    Redis进阶应用:Redis+Lua脚本实现复合操作
    一个项目的SpringCloud微服务改造过程
    中间件增强框架之-CaptureFramework框架
    关系型数据库全表扫描分片详解
    AI中台——智能聊天机器人平台的架构与应用(分享实录)
    如何设计实时数据平台(设计篇)
  • 原文地址:https://www.cnblogs.com/yzvictory/p/5714135.html
Copyright © 2020-2023  润新知