jer*_*lei 11 block objective-c ios
在Apple的文档中说:块文字(即^ {...})是表示块的堆栈本地数据结构的地址.因此,堆栈本地数据结构的范围是封闭的复合语句,因此您应该避免以下示例中显示的模式:
void dontDoThis() {
void (^blockArray[3])(void); // an array of 3 block references
for (int i = 0; i < 3; ++i) {
blockArray[i] = ^{ printf("hello, %d\n", i); };
// WRONG: The block literal scope is the "for" loop.
}
//for example I invoke the block here
blockArray[1]();
}
void dontDoThisEither() {
void (^block)(void);
int i = random():
if (i > 1000) {
block = ^{ printf("got i at: %d\n", i); };
// WRONG: The block literal scope is the "then" clause.
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我不知道应该避免哪些模式.看起来我可以调用与块定义具有相同文字范围的块,例如在"if"或"for"语句后面.你能帮我解释一下吗?
我认为对指针的类比如下.
void foo() {
int *block = NULL;
{
int a;
block = &a;
}
// `block`, even though defined here, points to
// an invalid memory address.
}
Run Code Online (Sandbox Code Playgroud)
通常,块文字本身仅存在于其定义的块中,因此当离开该块时,文字消失(就像a上面示例中的变量一样),并且您留下了悬空指针.
因此,通常会将块复制到堆中以供将来使用.非ARC代码使用block_copy和朋友.复制到堆中还会捕获块使用的所有相关变量(可能会创建保留周期).
在实践中,所有这些都被ARC,属性和类的使用所避免.您copy在类中定义属性,然后只为其分配块.如果让编译器生成getter/setter,则块文本将自动复制到堆中.
@interface Bla : NSObject
@property (nonatomic, copy) void (^blockProperty)(int i);
@endf
...
Bla *bla = [[Bla alloc] init];
{
bla.blockProperty = ^(int i) { printf("%d", i); };
}
// bla.blockProperty now points to a heap copy of the block literal from above,
// so it's not dangling.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
506 次 |
| 最近记录: |