在iOS中创建自己的完成块

6

我有一个对象需要花费很长时间来完成某些任务(例如从服务器下载数据)。

我该怎么写自己的完成块,以便我可以在对象完成任务时运行它...

[downloader doSomeLongThing:^(void) {    //do something when it is finished}];

我不确定如何将此块保存在下载器对象中。


你是否想知道如何编写一个接受 block 的方法?http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxUsing.html#//apple_ref/doc/uid/TP40007502-CH5-SW1 - James Boutcher
现在我明白为什么某些人会用Xcode这个标签(虽然那样做是错误的),但为什么是“最大公约数”呢? - user529758
哈哈!我没有放那个标签。我放了GCD,意思是Grand Central Dispatch。它一定被改变了。 - Fogmeister
2个回答

10

你可以复制这个代码块然后调用它:

typedef void (^CallbackBlk)();

@property (copy) CallbackBlk cb;

- (void)doSomething:(CallbackBlk)blk
{
    self.cb = blk;

    // etc.
}

// when finished:
self.cb();

7

由于您在回调函数中没有使用任何参数,因此可以使用标准的dispatch_block_t,而且既然只是在长时间进程完成时回调它,就没有必要使用属性来跟踪它。您可以这样做:

- (void)doSomeLongThing:(dispatch_block_t)block
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Perform really long process in background queue here.

        // ...

        // Call your block back on the main queue now that the process 
        // has completed.
        dispatch_async(dispatch_get_main_queue(), block);
    });
}

然后您按照您指定的方式实现它:
[downloader doSomeLongThing:^(void) {
    // do something when it is finished
}];

谢谢,我会保存这个以备将来参考。在我的实际代码中有几个参数,我需要两个不同的块。这是为了完成/错误的 NSURLConnection,但我不能使用 sendAsynch...。 - Fogmeister
我明白了。在这种情况下,您可能还应该考虑查看AFNetworking。关于这些库是否使事情变得更好的争论仍在进行中。在我看来,基于块的API使AFNetworking成为一个非常简单和方便的库。您可以在此处查看它:https://github.com/AFNetworking/AFNetworking,并自行决定。 - Matt Long
谢谢。我会看一下的。我已经创建了我的类,现在它似乎运行良好,但我会考虑这个建议。 - Fogmeister
有人可以看一下我在这里的相关问题吗:https://dev59.com/EHvaa4cB1Zd3GeqPE5WE - marciokoko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接