Bla*_*use 4 xcode block objective-c ios
我想知道我是否做得对:
如果我有一个区块,我会这样做:
__weak MyClass *weakSelf = self;
[self performBlock:^{ //<< Should I use self, or weakSelf here?
[weakSelf doSomething];
} afterDelay:delay];
Run Code Online (Sandbox Code Playgroud)
但是如果块中存在块,会发生什么?这是正确的吗?
__weak MyClass *weakSelf = self;
[self performBlock:^{
[weakSelf doSomething];
[self performBlock:^{
[weakSelf doSomething];
} afterDelay:1.0f];
} afterDelay:delay];
Run Code Online (Sandbox Code Playgroud)
另外,在下面的功能中,我是否需要使用[块复制]?
- (void)performBlock:(void (^)(void))block afterDelay:(float)delay
{
if (block)
{
if (delay > 0)
{
[self performSelector:@selector(executeBlockAfterDelay:) withObject:[block copy] afterDelay:delay];
}
else
{
[self executeBlockAfterDelay:[block copy]];
}
}
}
- (void)executeBlockAfterDelay:(void(^)(void))block
{
if (block)
block();
}
Run Code Online (Sandbox Code Playgroud)
而不是实施-performBlock:afterDelay:,只需使用dipatch_after().除此之外,这不是传递给对象的消息,因此毫无疑问接收器的目标是什么.
实际上,这里根本没有内存管理问题.当一个对象保留一个块并且该块(可能是隐含的)保留该同一个对象时,通常只需要执行"弱自我"方法.但是,该对象不保留该块.框架保留它直到-performSelector:withObject:afterDelay:火灾,但这不是保留周期.
如果存在保留周期,则不应self在块中引用.因此,您的嵌套案例在调用消息时是错误的self而不是weakSelf.
最后,是的,您确实需要[block copy]在执行后保留一个块离开其声明的范围,或者将它传递给非特定于块的API.也就是说,当你传递一个块时,你不需要复制一个块,比如说,dispatch_async()因为这是一个块知道的API,它知道在必要时制作自己的副本.但-performSelector:withObject:afterDelay:不是块感知.它只是将其参数视为通用对象并保留它.因此,您必须在将块传递给它时复制该块.
在这种情况下(下面)使用强 self,因为块只复制了几秒钟.并且通常如果你想要self执行阻止,你希望它保持活着直到那个时候,所以强引用是完全可以的.
[self performBlock:^{
[self doSomething]; // strong is OK
} afterDelay:delay];
Run Code Online (Sandbox Code Playgroud)
块内阻塞?在你的情况下,这两个块只是延迟一次性块,所以与上面相同,使用强.但是块之间存在差异.如果您将块存储较长时间,也许对于多次调用,您应该避免保留周期.
例:
self.callback = ^{
[self doSomething]; // should use weakSelf
};
Run Code Online (Sandbox Code Playgroud)
这可能会导致保留周期.实际上,它取决于块的使用方式.我们看到该块被存储(复制)在属性中供以后使用.但是,您可以通过使不再使用的块无效来阻止保留周期.在这种情况下:
self.callback(); //invoke
self.callback = nil; //release
Run Code Online (Sandbox Code Playgroud)
使用ARC时,您不必自己复制块.在添加块之后,早期版本中存在错误,但现在ARC下的编译器知道何时复制块.在这种情况下复制它很聪明:
[self performSelector:@selector(executeBlockAfterDelay:) withObject:block afterDelay:delay];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2865 次 |
| 最近记录: |