专栏首页蜉蝣禅修之道ARC无效时block的赋值

ARC无效时block的赋值

总所周知,当ARC无效时,block默认是在栈区或全局数据区,要想复制到堆区,需要一些特殊手段,这些手段在《Objective-C高级编程》都有介绍,例如将block声明为类的属性,block调用copy方法,作为函数返回值等等。

但是《高级编程》里有个地方写错了,不过也有可能书上没写清楚是否开启ARC,不过通过我的实验验证,当ARC关闭时,在类方法中给block属性赋值,如果不加上copy,还是在栈上,但是在对象外部赋值却是在堆上。具体过程看下面代码:

#import <Foundation/Foundation.h>
typedef void(^blk_t)();
@interface MyObject : NSObject
@property(nonatomic,copy) blk_t blk;
@property(nonatomic,retain)NSString* name;
-(void)setInnerBlock;
@end
#import "MyObject.h"

@interface MyObject(){
    int _index;
}

@end
@implementation MyObject
void retainCount(NSObject* __unsafe_unretained obj){
    NSLog(@"the retain count is:%ld",CFGetRetainCount((__bridge CFTypeRef)obj));
}
-(instancetype)init{
    self=[super init];
    if(self){
//                typeof(self) __block wself=self;
        retainCount(self);

    }
    return self;
}
-(void)setInnerBlock{
    _blk=^(){
        self->_index=10;
    };
}

@end

此时如果定义一个MyObject对象,调用setInnerBlock后,再调用_blk,将会报出BAD_ADDRESS错误,因为栈上的block已经被销毁,blk这时是野指针。要是查看blk的class也是stackblock,正确的赋值方式如下:

    MyObject* obj=[[MyObject alloc] init];
    int a=0;
//    [obj setInnerBlock];
    obj.blk=^(){
        NSLog(@"Block被调用:%d",a);
    };
    obj.blk();
    NSLog(@"Block类型:%@",[obj.blk class]);

希望对大家有所帮助

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • defer in C++/Objc

    写过swift的同学应该都知道defer这个关键字,可以让我们在函数return之前执行指定的代码,这对于有多个提前return而忘记释放资源的函数来说,简直不...

    forrestlin
  • Simplex单纯性算法的Python实现

    forrestlin
  • bing Maps学习笔记(一)地区支持

    forrestlin
  • 面向对象(二)【类的成员及修饰符】

    在上述类的成员中,普通字段是存储在对象之中的;其他成员均是存储在类中,也就是说无论创建了多少个对象,对象本身只保留成员中的普通字段,其他成员均存储在类中。

    用户1432189
  • Javascript对象的方法赋值

    Javascript对象编程学习中,一直不能很好的掌握对象的属性(property)和方法(method)。今天在写代码过程中,又犯了一个低级错误。 <!DOC...

    八哥
  • javascript经典面试题之拷贝

    今天和大家一起来探讨一下javascript中的拷贝,使用拷贝的情况,要根据javascript的数据类型来定,javascript的数据类型分为基础类型和引用...

    挥刀北上
  • 「R」对象大小——R存储真的会占很大空间吗?

    在上一篇文章中介绍过列表存储的不是实际的值,而是指向值的引用,所以一个列表的大小比我们预期的可能要小的多。

    王诗翔呀
  • 2014CENCE&CCS大会闭幕 劲爆内容大盘点

    ? 第十六届CENCE中国企业网络通信大会&第七届CCS云计算高峰论坛暨展览于昨日落下帷幕,会中观点激荡,“高大上”厂商云集,各类新品频出。以下来看小编...

    静一
  • rabbitmq搭建集群踩坑记

    三台节点启动之后,想要使用s146作为集群主节点,在s151上将该节点加入s146集群时,报如下错误。

    我是李超人
  • 如何开发YUI3的扩展

    YUI是Yahoo发布的一个JS框架,虽然不如jQuery简单,但是如果你是要做一些复杂的事情的时候,有一个合适量级的框架还是能有用不少。

    大江小浪

扫码关注云+社区

领取腾讯云代金券