如何在Objective-C中的属性中存储块?

Pio*_*pla 76 objective-c objective-c-blocks

我想将objective-c块存储在属性中供以后使用.我不知道该怎么做所以我google了一下,关于这个主题的信息很少.但我最终设法找到了解决方案,我认为可能值得为像我这样的其他新手分享.

最初我认为我需要手动编写属性才能使用Block_copy和Block_release.

幸运的是,我发现块是NSObjects- copy/ - release等价于Block_copy/ Block_release.所以我可以@property (copy)用来自动生成setter和getter.

Dav*_*ong 135

编辑:更新为ARC

typedef void(^MyCustomBlock)(void);

@interface MyClass : NSObject

@property (nonatomic, copy) MyCustomBlock customBlock;

@end

@implementation MyClass

@end

MyClass * c = [[MyClass alloc] init];
c.customBlock = ^{
  NSLog(@"hello.....");
}

c.customBlock();
Run Code Online (Sandbox Code Playgroud)

  • 是戴夫,真的.我也可以搜索并查看它们.解释是模糊的,就像你使用副本"使它们真正存活在堆栈框架中".我认为保留对象也会这样做.没有解释如何分配堆栈的块.然而,评论确实链接到一篇文章 - http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html,它解释得很好.请参阅"块是有点奇怪的对象".所以谢谢! (29认同)
  • 任何人都知道为什么你应该使用的块(非原子的,复制的)而不是(非原子的,保留的)?通常使用保留,我无法找到解释为什么使用副本块的任何地方. (5认同)
  • 我/我们到处都使用`nonatomic`.它应该是默认的IMO.`atomic`使得更大的二进制文件,更低的性能(锁定所有访问器)并且它似乎承诺线程安全 - 通常必须在比属性访问器更高的级别上解决. (3认同)
  • @JoeBlow如果你担心从多个队列同时获取和设置属性的值,你只需要原子性.否则没关系. (2认同)

Ste*_*mer 98

或者,没有typedef

@property (copy, nonatomic) void (^selectionHandler) (NSDictionary*) ;

  • 为了澄清,因为语法是如此不透明,这是一个名为"selectionHandler"的块属性,它接受NSDictionary*参数并返回void. (17认同)

Jor*_*rez 9

您可以在第83页开始的WWDC 2012会话712中找到对此的非常好的解释.在ARC下保存块的正确方法如下:

@property(strong) my_block_type work;
Run Code Online (Sandbox Code Playgroud)

小心保留周期.一个好的解决方法是在不再需要时将块设置为nil:

self.work = nil;
Run Code Online (Sandbox Code Playgroud)

  • 只有ARC.在MRC下,这是错误的.但是`copy`在MRC和ARC下都能正常工作 (2认同)