0

我不确定如何处理块。例如,在我的 viewDidLoad 中,我调用了一个函数“useDocument”来设置 Core Data。我希望一旦 Core Data 准备好使用,就会调用另一个函数来处理一些查询。就像 ASIHTTPRequest一样,当客户端收到响应时,会调用一个函数来处理响应。

我猜触发函数不是使用块的正确方法。但正确的方法是什么?

- (void)useDocument
{
    if (!self.database) {
        self.database = [DataModelDocument sharedDocument];
    }

    if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
        // does not exist on disk, so create it
        [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
                if (!success) {
                    NSLog(@"database doesn't exist on disk, we fail to create it");
                }
        }];
    } else if (self.database.documentState == UIDocumentStateClosed) {
        // exists on disk, but we need to open it
        [self.database openWithCompletionHandler:^(BOOL success) {
            if (!success) {
                NSLog(@"database exists on disk, but we fail to open it");
            }
        }];
    } else if (self.database.documentState == UIDocumentStateNormal) {
        // already open and ready to use
    }
}
4

2 回答 2

1

没有使用块的正确方法,因为没有使用函数的正确方法。

块是函数。不仅仅是一个功能,但没有太大的不同。所以让我们暂时忘记这些差异。职能。

使用一个函数,你会写出类似的东西

void callback (BOOL success) {
    if (success) {
        // do something useful
    }
}

[database openWithCallback: &callback];

这里有某种小字节序。是的。

块允许您在线编写回调。

[self.database openWithCompletionHandler: ^(BOOL success) {
    if (!success) {
        // oops, handle that
    }
}];

在那种特殊情况下,块不能解决任何功能无法解决的问题。它们的成本更高。

当你大量使用它们时,好处就会显现出来。如果您将操作编写为完全异步的,则可以以简化的方式编写代码。

伪代码:

dispatch block: ^(){
    some heavy computation here
    dispatch block: ^(){
        computation done, update the UI or something
    }
}

非常简单的例子。当然,用函数编写它是完全可能的。但不那么可读。

现在假设您正在调度大量的块,您可以创建块组,然后在组完全执行时执行一个块。非常容易写,非常容易阅读。这开始成为处理无处不在的函数指针的噩梦。

现在,是什么让块不仅仅是一个函数?

块是一个函数。有上下文。块可以访问同一范围内的变量。在上面的简单示例中,工作块可以访问调用范围,而完成块可以访问调用范围和工作块范围。当然,这可以通过功能和结构来完成。有很多代码,更难阅读。块更优雅地解决了这个问题。

我建议您阅读有关 Grand Central Dispatch 的内容。这显然是块显示其真正潜力和表现力的地方。

于 2012-06-19T08:55:07.133 回答
0

您可以将块视为一种“有状态线程”。我强调“有点”。它是将代码和变量封装在一个漂亮整洁的小“代码块”中。

您可以使用 __block 将变量从块外部带入范围,并在周围代码的其余部分完成时运行该块。

在这种情况下,您使用的是完成块。如果您愿意,您可以在其中调用方法,只要调用它们的适当时间是在它周围的所有代码完成之后。

于 2012-06-19T03:41:25.220 回答