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

Seg fault while using the block getter message

我是积木新手。我试图在命令行中运行这段代码,以了解块的工作原理。当我通过命令行运行代码时,出现段错误。但是当我使用 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] <NSMallocBlock: 0x1003096a0>

然而,当我在命令行中运行它时,我得到了这个:-

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

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

分段错误:11

我怎么会出现段错误??请协助。谢谢

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

当你这样做时:

block = ^void...

你直接赋值给 属性 的支持变量,这将绕过 copy 属性的语义。如果该块未被复制,它将在 run returns 时被销毁,然后您将遇到内存错误。

更改为:

self.block = ^void...

以便使用 属性 setter 并完成复制。

HTH

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

附录

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

如果没有 ARC,您必须如上所述使用self.block = ...才能应用属性中的copy。使用 ARC 即使 属性 setter 本身被绕过,ARC 也会插入一个块副本作为分配的一部分。

在这两种情况下,您都应该使用当前版本的 Xcode/the Clang 编译器进行编译。如果您 select 在 Xcode 中将项目类型设为 "Command Line Tool",则生成的二进制文件是命令行二进制文件。要快速找到它,您可以右键单击 Xcode 和 select "Show in Finder" 中的二进制名称。 运行 终端中的那个二进制文件,它会工作。