实现采用块作为回调的方法


70

我想写一个类似这样的方法:

+(void)myMethodWithView:(UIView *)exampleView completion:(void (^)(BOOL finished))completion;

我基本上已经从Apple的一种类方法中删除了以下语法UIView

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

并希望它像这样使用:

[myFoo myMethodWithView:self.view completion:^(BOOL finished){
                     NSLog(@"call back success");
                 }];

我的问题是我该如何实施?如果有人可以指出正确的文档,那将是很好的,并且非常感谢一个非常基本的示例(或者在Stack Overflow上有类似的答案-我找不到)。对于委托人,我还是不太了解,以确定这是否是正确的方法!

我已经在实现文件中给出了一个我期望的粗略示例,但是由于我找不到信息,所以猜测是可行的。

+ (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion {
    // do stuff

    if (completion) {
        // what sort of syntax goes here? If I've constructed this correctly!
    }

}

我想知道为什么finished在这个例子中没有人提到参数类型中的参数是不必要的...
funct7

Answers:


84

您可以像常规函数一样调用一个块:

BOOL finished = ...;
if (completion) {
    completion(finished);
}

因此,这意味着使用您的示例实现完整的块函数如下所示:

+ (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion {
    if (completion) {
        completion(finished);
    }
}

这很痛苦,很简单,非常感谢!网站说接受答案为时尚早,一旦我回到计算机上,我就会这样做
克里斯(Chris)

还要注意,在您的示例中,您是在堆栈上创建块的,因此有可能该块在执行之前就死掉。为避免这种情况,请在您的接受块的方法中使[[completion copy] autorelease]自动释放。
Timur Kuchkarov

@TimurKuchkarov-您可以跳过一些代码,以便我可以看到[完成副本]在方法中的位置吗?我的简单头脑有点困惑:)

1
“通常,您不需要复制(或保留)块。仅当您希望在声明了该块的作用域被破坏后使用该块时,才需要进行复制。复制将一个块移动到堆中”。一个很好的链接是-mikeash.com/pyblog/…。对于我来说,我通常在传递块的方法开始处进行复制。
Timur Kuchkarov 2013年

1
@ErhanDemircicompletion是实际的块。它在方法签名中定义。(void(^)(BOOL finish))completion允许调用用作回调的completion()方法。看看苹果的文档:developer.apple.com/library/ios/documentation/cocoa/conceptual/...
乔纳森-萨林格

5

我强烈建议您阅读Blocks以了解发生了什么。


当我复制粘贴+(void)myMethod:(UIView *)exampleView完成:(void(^)(BOOL已完成))completion {if(completion){ 我收到“未声明标识符的使用已完成” ....
alex440

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.