我写了一些使用Objective-C block的代码,但是结果让我感到困惑。
@interface MyTest : NSObject
@end
@implementation MyTest
- (void)test {
NSArray *array = [self array1]; // ok
// NSArray *array = [self array2];// crash
// NSArray *array = [self array3];// ok again
dispatch_block_t block0 = (dispatch_block_t)[array objectAtIndex:0];
block0();
dispatch_block_t block1 = (dispatch_block_t)[array objectAtIndex:1];
block1();
}
- (NSArray *)array1 {
int a = 10;
NSMutableArray *array = [NSMutableArray array];
[array addObject:^{
NSLog(@"block0: a is %d", a);
}];
[array addObject:^{
NSLog(@"block1: a is %d", a);
}];
return array;
}
- (NSArray *)array2 {
int a = 10;
return [NSArray arrayWithObjects:^{
NSLog(@"block0: a is %d", a);
}, ^{
NSLog(@"block1: a is %d", a);
}, nil];
}
- (NSArray *)array3 {
int a = 10;
return [NSArray arrayWithObjects:^{
NSLog(@"block0: a is %d", a);
},[^{
NSLog(@"block0: a is %d", a);
} copy], nil];
}
@end
我感到困惑的是:
- 数组array2为什么会崩溃?array1和array2真正的区别是什么?
- 我读过一些文章,说块拷贝会将块从栈移到堆中,但在array1方法中,我没有进行拷贝,它仍然可以正常工作。在array3中,我只是拷贝第二个块,它就可以正常工作。为什么呢?
- 在使用块时,我必须在哪里使用拷贝?
顺便说一下,我在ARC下的Xcode 4.6中运行了代码。谢谢。
arrayWithObjects:
和addObject:
没有明确说明它们复制其参数。 - ipmccid
。它无法知道接下来的可变参数的类型(例如printf
中可变参数可以是任意类型),因此不会复制它们。 - ipmcc