使用块getter消息时出现段错误

时间:2015-01-03 18:05:00

标签: objective-c cocoa-touch objective-c-blocks

我是块新手。我试图在命令行中运行这段代码,以了解块的工作原理。当我通过命令行运行代码时,我遇到了Seg故障。但是当我使用Xcode运行相同的代码时,它编译并运行得很好。这是代码: -

#import <Foundation/Foundation.h>

@interface BlockTest:NSObject
@property (copy) void (^block) (void);
-(void)run; 
@end

@implementation BlockTest
@synthesize block;
-(void)run{
   NSObject *obj= [[NSObject alloc] init];

   block = ^void (void){
   NSLog(@"my object- %@",obj);
   };

 NSLog(@"running the block...");
 block();
}
@end

int main(){
  BlockTest *test= [[BlockTest alloc] init];
  [test run];
  NSLog(@"%@",[test block]);
}

这是我在Xcode中运行时的输出: -

2015-01-03 23:13:41.187 BlockTest [999:41316]正在运行该区块...

2015-01-03 23:13:41.189 BlockTest [999:41316]我的对象 -

2015-01-03 23:13:41.190 BlockTest [999:41316]&lt; NSMallocBlock :0x1003096a0&gt;

当我在命令行中运行它时,我明白了: -

2015-01-03 23:32:50.441 BlockTest [1115:47957]正在运行该块......

2015-01-03 23:32:50.443 BlockTest [1115:47957]我的对象 -

分段错误:11

为什么我会遇到Seg故障?请帮助。感谢名单

1 个答案:

答案 0 :(得分:2)

缺少详细信息,例如您使用的是MRC还是ARC?所以这是一个猜测。

当你这样做时:

block = ^void...

您将直接分配给属性的支持变量,这将绕过copy属性的语义。如果未复制该块,则在run返回时将销毁该块,然后您将收到内存故障。

更改为:

self.block = ^void...

以便使用属性设置器并完成复制。

HTH

顺便说一句:这些天您不需要@synthesize,将自动创建属性并使用名为 _property 的支持变量。通常,您应始终使用 self.property 设置属性,因为它支持KVO和copy属性。您还应该确保使用ARC。

<强>附录

从评论(关于这个问题和主要问题)看来,您正在使用不同的编译器编译代码,以便在命令行上运行。这似乎可以解释这些差异。

如果没有 ARC,您必须使用self.block = ...,如上所述,以便应用copy属性。使用ARC,即使属性设置器本身被绕过,ARC也会在分配时插入块副本。

在这两种情况下,您都应该使用当前版本的Xcode / Clang编译器进行编译。如果在Xcode中选择项目类型为“命令行工具”,则生成的二进制文件是命令行二进制文件。要快速找到它,您可以右键单击Xco​​de中的二进制名称,然后选择“在Finder中显示”。在终端中运行该二进制文件,它将起作用。