学习block - iOS

一、block

1、block分类:NSGlobalBlock,NSMallocBlock,NSStackBlock

三种block各自的存储域如下图:

  • _NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。
  • _NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
  • _NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁

2、block特性:

a、捕获外部变量

int a = 10;
void (^block)(void) = ^{NSLog(@"a的值 - %d",a);
};a = 2;
block();

输出结果如下:

 

通过结果发现,a = 10,而不会a = 2,可以知道默认情况下block只能访问,不能修改局部变量的值。

那我们如何输出a = 2;呢?

通过使用__block修饰外部变量,代码如下:

__block int a = 10;
void (^block)(void) = ^{NSLog(@"a的值 - %d",a);
};
a = 2;
block();

结果如下:

 

为什么使用__block修饰的外部变量的值就可以被block修改呢? 我们使用clang将代码转换为C++文件发现。 没有加__block 的结构体:

struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;int a;__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}
};

增加了__block的结构体:

struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;__Block_byref_a_0 *a; // by ref__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}
};

我们发现了局部变量a加上__block修饰符跟block一样变成了一个__Block_byref_a_0结构体类型的自动变量实例。然后我们会使用一个__forwarding成员变量来间接的访问a变量。

b、匿名函数 -- 保存代码块 -- 非常灵活(但是嵌套层非常深,不建议使用block,因为代码调试复杂,不便于直观性)

3、block的定义与使用

a、无参数无返回值

void (^blockOne)(void) = ^(void) {NSLog(@"无参数无返回值");
};
blockOne();

b、有参数,无返回值

void (^blockTwo)(int a) = ^(int a) {NSLog(@"@ = %d我就是block,有参数,无返回值",a);
};
blockTwo(100);

c、有参数,有返回值

int (^blockThree)(int,int) = ^(int a,int b) {NSLog(@"@ = %d我就是block,有参数,有返回值",a+b);return a+b;
};
blockThree(5,10);

d、无参数,有返回值

 int (^blockFour)(void) = ^(void) {NSLog(@"无参数,有返回值");return 3;
};
blockFour();

e、实际开发应用,常常用typedef定义block

用typedef定义一个block:

typedef int (^blockThree)(int,int) ;

这时,blockThree就成为了一种block类型,在定义类的属性时:

@property (nonatomic, copy) blockThree myblock;

使用时:

self.myblock = ^int (int, int);


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部