我正在尝试编写一个通用函数来启动和结束事件到我的Obj-C(iOS)应用程序中。我正在定义- (void)startEvent:(void (^)())completion
。在这个函数的主体中,我采取了一个启动动画的动作。我需要的是在特定时间间隔过去时调用completion
。
因此,我复制completion
并将其分配给全局变量(在类范围内)。
我就是这样做的:
void (^startEventCompletionClosure)();
- (void)startEvent:(void (^)())completion {
// side note: I have NO access to "complete" closure of - [UIView animateWithDuration:...]
...
[self performSelector:@selector(startEventCompleted) withObject:nil afterDelay:kDealy];
startEventCompletionClosure = [completion copy];
}
- (void)startEventCompleted {
startEventCompletionClosure();
[startEventCompletionClosure release];
}
但是,我有几个问题:
copy
呢?是不是只能retain
呢?[... copy]
和[... retain]
?感谢阅读!
答案 0 :(得分:2)
这是处理此问题的更好方法吗?
根据您的用法,您可能希望将其存储为实例变量(除非您确实希望在类之间共享块,因此随时更改所有类startEvent:
被称为。)
__block是NSObject吗? C声明?
这是一个C存储限定符。
为什么我要复制它?是不是只能保留它?
你可以保留它,但它可能不会做你想做的事情。在C和Objective-C中,在堆栈上创建块。复制时,它(以及它关闭的任何变量)都会复制到堆中。如果保留它,则它及其变量不被复制到堆中。
如果它不是Obj-C对象,为什么我可以调用
[... copy]
和[... retain]
原样?
万。 :)更严重的是,在Objective-C中,块被设计为充当Objective-C对象。 (它类似于您可以在NSString
和CFStringRef
之间无缝投射的原因 - 这些对象旨在实现这一目标。)
答案 1 :(得分:1)
首先,我们将它们称为“块”,而不是Objective-C中的“闭包”。其次,-performSelector:withObject:afterDelay:
是我们在阻止之前使用的东西。这些天你应该使用dispatch_after()
。最后,块是对象,它们符合NSObject
协议。
答案 2 :(得分:0)
UIView现在也有很好的基于块的动画方法......
animateWithDuration:动画: animateWithDuration:动画:完成: animateWithDuration:延迟:选择:动画:完成:
[UIView animateWithDuration:kAnimationDurationTime animations:^{
// animate some animatable properties
// do some other stuff
} completion:^(BOOL finished) {
// code that you want to run
// when the animation has finished
}];
我发现这是一种非常有用的动画制作方法。