Block使用中的一些疑问解答
来源:互联网 发布:黑客使用什么软件 编辑:程序博客网 时间:2024/04/26 01:58
本文主要是阐述一下Block中如何的使用外部变量以及block本身的内存管理。
先定义一个block变量,作为后续的例子中使用:
- typedef void(^BlockCC)(void);
- BlockCC _block;
1、block中引用外部变量
block中可以直接使用外部的变量,比如
- int number = 1;
- _block = ^(){
- NSLog(@"number %d", number);
- };
那么实际上,在block生成的时候,是会把number当做是常量变量编码到block当中。可以看到,以下的代码,block中的number值是不会发生变化的:
- int number = 1;
- _block = ^(){
- NSLog(@"number %d", number);
- };
- number = 2;
- _block();
则输出的值为 1,而不是2。原因就是如上所说。
如果要在block中尝试改变外部变量的值,则会报错的。对于这个问题的解决办法是引入__block标识符。将需要在block内部修改的变量标识为__block scope。更改后的代码如下:
- __block int number = 1;
- _block = ^(){
- number++;
- NSLog(@"number %d", number);
- };
而这个时候,其实block外部的number和block内部的number指向了同一个值,回到刚才的在外部改变block的例子,它的输出结果将是2,而不是1。有兴趣的可以自己写一个例子试试。
2、block自身的内存管理
block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。比如下面的例子。
我在view did load中创建了一个block:
- - (void)viewDidLoad
- {
- [superviewDidLoad];
- int number = 1;
- _block = ^(){
- NSLog(@"number %d", number);
- };
- }
并且在一个按钮的事件中调用了这个block:
- - (IBAction)testDidClick:(id)sender {
- _block();
- }
此时我按了按钮之后就会导致程序崩溃,解决这个问题的方法就是在创建完block的时候需要调用copy的方法。copy会把block从栈上移动到堆上,那么就可以在其他地方使用这个block了~
修改代码如下:
- _block = ^(){
- NSLog(@"number %d", number);
- };
- _block = [_blockcopy];
同理,特别需要注意的地方就是在把block放到集合类当中去的时候,如果直接把生成的block放入到集合类中,是无法在其他地方使用block,必须要对block进行copy。不过代码看上去相对奇怪一些:
- [array addObject:[[^{
- NSLog(@"hello!");
- } copy] autorelease]];
3、循环引用
这一点其实是在第一点的一个小的衍生。当在block内部使用成员变量的时候,比如
- @interface ViewController : UIViewController
- {
- NSString *_string;
- }
- @end
在block创建中:
- _block = ^(){
- NSLog(@"string %@", _string);
- };
这里的_string相当于是self->_string;那么block是会对内部的对象进行一次retain。也就是说,self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。
修改方案是新建一个__block scope的局部变量,并把self赋值给它,而在block内部则使用这个局部变量来进行取值。因为__block标记的变量是不会被自动retain的。
- __block ViewController *controller = self;
- _block = ^(){
- NSLog(@"string %@", controller->_string);
- };
先写到这里,基本是我在用block时候碰
到的一些问题。需要更详细的解释,可以看看《Adanced Mac OS X Programming》这本书,推荐给大家。
到的一些问题。需要更详细的解释,可以看看《Adanced Mac OS X Programming》这本书,推荐给大家。
转自:Jesse
- Block使用中的一些疑问解答
- Block使用中的一些疑问解答
- Block使用中的一些疑问解答
- Block使用中的一些疑问解答
- Block使用中的一些疑问解答(包括循环引用问题的解决)
- 关于Access发布使用打包软件的一些疑问解答
- 关于Access发布使用打包软件的一些疑问解答
- spi一些疑问的解答
- 关于Storm的一些疑问解答
- Css中的一些疑问
- 疑问解答
- 关于ip_free中的一些疑问
- 学习过程中的一些疑问
- 计算机网络一些基本疑问解答和基础常识(一)
- jquery的一些疑问和解答(待扩展)
- Unity学习笔记 一些小疑问解答记录
- DB疑问解答之 --- 为什么使用树结构组织索引
- 关于Postgres的oid使用疑问解答.md
- 【91xcz】什么是win7的移动中心?如何快速打开
- 让ProgressDialog在setCancelable(false)时按返回键可dismiss
- 【Spring学习笔记】Spring事务管理(一)
- 提高php代码质量 36计
- 【Hibernate中load和get的区别】
- Block使用中的一些疑问解答
- http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html
- Hibernate注解入门
- ReverseAjax
- Java - 正则表达式 - Pattern - Matcher
- List<对象>去重
- Qt布局管理
- win2003 server sp2环境配置apache和mysql注意事项
- c++ primer 习题9.39