block 的结构

396 阅读1分钟

关于block的一个常见崩溃

TaskObject* objc = [TaskObject new];
    objc.successBlock = ^(NSDictionary * _Nonnull data) {
        NSLog(@"data:%@",data);
    };
    objc = nil;

    objc.successBlock(@{@"1":@"3"});

大家猜测一下,上边的代码是否会crash?按照以往的经验,对象已经nil,给一个nil对象发消息,是不会crash的,但是blcok跟普通的属性不太一样,我打印了一下:

可以看到,虽然对象是nil啦,但对应的block是null,并不是nil,所以会crash。所以我们之后在操作blcok之前要小心,一定要进行判空操作。

关于block的讲解,这两篇写的很好了

www.cnblogs.com/lybSkill/p/…

www.cnblogs.com/lybSkill/p/…

segmentfault.com/a/119000001…

github.com/Sunxb/Blog/…

首先要明白 .和->的区别 blog.csdn.net/faihung/art…

需要补充的是, __block int c = 10; 如果这样的话,clang成C++的代码是怎样的

struct __Block_byref_c_0 {
 void *__isa;
__Block_byref_c_0 *__forwarding;
int __flags;
int __size;
int c;
};

struct __main_block_impl_0 {
 struct __block_impl impl;
 struct __main_block_desc_0* Desc;
 int *d;
 __Block_byref_c_0 *c; // by ref
 __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_d, __Block_byref_c_0 *_c, int flags=0) : d(_d), c(_c->__forwarding) {
   impl.isa = &_NSConcreteStackBlock;
   impl.Flags = flags;
   impl.FuncPtr = fp;
   Desc = desc;
 }
};

int main(int argc, const char * argv[]) {
   /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 



       __attribute__((__blocks__(byref))) __Block_byref_c_0 c = {(void*)0,(__Block_byref_c_0 *)&c, 0, sizeof(__Block_byref_c_0), 10};
       static int d = 10;
       myBlock blockObj = ((void (*)(int, int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, &d, (__Block_byref_c_0 *)&c, 570425344));


       a = 99;
       b = 99;
       (c.__forwarding->c) = 99;
       d = 99;

       ((void (*)(__block_impl *, int, int))((__block_impl *)blockObj)->FuncPtr)((__block_impl *)blockObj, 20, 30);

   }
   return 0;
}

对应的oc
int main(int argc, const char * argv[]) {
   @autoreleasepool {
       // insert code here...
//        NSLog(@"Hello, World!");

       __block int c = 10;
       static int d = 10;
       myBlock blockObj = ^(int m , int n){

           NSLog(@"a:%d-b:%d-c:%d-d:%d", a,b,c,d);
       };
       
       
       a = 99;
       b = 99;
       c = 99;
       d = 99;
       
       blockObj(20,30);
       
   }
   return 0;
}

2.针对对象是怎样的 可以参照文章 www.cnblogs.com/lybSkill/p/…

git.dev.tencent.com/Jingya_lu/C… 其中位运算demo

3.自己对block的理解:它就是个函数指针

  • myblock(argu,argu),是调用这个函数
  • myblock() = ^(argu1,argu2)myblock{

};//定义声明这个函数