Ios 是否可以避免编写此块调用代码';向后';?

Ios 是否可以避免编写此块调用代码';向后';?,ios,objective-c,objective-c-blocks,grand-central-dispatch,Ios,Objective C,Objective C Blocks,Grand Central Dispatch,我在Objective C中有一个异步方法,您将完成处理程序传递给它 我希望有条件地在两个不同的对象上运行此方法两次,然后处理结果 我能找到的唯一方法是“向后”编写代码,如下所示 这意味着我在体系结构方面存在重大缺陷。有更好的办法吗 定义.h myController.h 这意味着我在体系结构方面存在重大缺陷。有更好的办法吗 不,没有。也许你只需要调整你的观点 在定义块之前,不能使用变量来调用块,因此类似于完成处理程序的代码将始终位于调用它的代码之前。这没什么错。这就像在执行之前告诉别人你的计划

我在Objective C中有一个异步方法,您将完成处理程序传递给它

我希望有条件地在两个不同的对象上运行此方法两次,然后处理结果

我能找到的唯一方法是“向后”编写代码,如下所示

这意味着我在体系结构方面存在重大缺陷。有更好的办法吗

定义.h

myController.h

这意味着我在体系结构方面存在重大缺陷。有更好的办法吗

不,没有。也许你只需要调整你的观点

在定义块之前,不能使用变量来调用块,因此类似于完成处理程序的代码将始终位于调用它的代码之前。这没什么错。这就像在执行之前告诉别人你的计划:离开办公室后,我会在杂货店停下来。计算机语言通常没有实际的将来时态,但在用将来时态编写代码之前,考虑定义块可能会有所帮助


如果在导致它运行的代码之前有一个完成代码确实让您感到困扰,那么您有时可以将该代码放在它自己的方法中,这样完成块本身只包含对该方法的调用。当然,该方法可以遵循调用它的代码(但在使用它之前仍需要定义完成块本身)。

您有重复的代码,因此应该将其分离为一个方法:

- (void) processPoint:(FAPlacePoint*)point completionHandler:(void (^)(FAPlacePoint *savedPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed))completionHandler
{
    if (point.currentLocation)
        [self reverseGeocodeThenSavePlacePoint:point completion:completionHandler];
    else
    {
        FAPlacePoint * pp = [self storePlacePoint:point];
        BLOCK_SAFE_RUN(completionHandler, pp, YES, YES);
    }
}
这允许您避免将块存储在变量中以避免重复它们。因此,您的代码减少到:

[self processPoint:originPlacePoint completionHandler:^void (FAPlacePoint *savedOriginPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed) {
    [self processPoint:destinationPlacePoint completionHandler:^void (FAPlacePoint *savedDestinationPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed) {

        // Everything is finished.  Do something with savedOriginPP and savedDestinationPP

    }];
}];

我不确定你是从哪里得到这样的想法的:在使用块之前必须定义块。任何采用块参数的方法都可以在调用中内联定义块。因此,要按嵌套顺序运行一系列块。@jshier更准确地说,在使用块变量调用块之前,必须先定义块变量。当然,您可以使用块本身作为参数,但是您会注意到OP希望从两个不同的位置调用同一块。Ken Thomases的回答有助于避免在这种特殊情况下需要这样做。一般来说,如果你要在多个地方使用同一个块,你需要把它赋给一个变量,在你使用这个变量调用块之前,你显然需要这样做。我非常感谢你的回答。我给Ken Thomases答案的唯一原因是,严格地说,他提供了解决所述问题的代码。@CarlosP谢谢,不用担心——Ken的答案也是很好的。很高兴你发现这两个答案都很有用。
- (void) processPoint:(FAPlacePoint*)point completionHandler:(void (^)(FAPlacePoint *savedPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed))completionHandler
{
    if (point.currentLocation)
        [self reverseGeocodeThenSavePlacePoint:point completion:completionHandler];
    else
    {
        FAPlacePoint * pp = [self storePlacePoint:point];
        BLOCK_SAFE_RUN(completionHandler, pp, YES, YES);
    }
}
[self processPoint:originPlacePoint completionHandler:^void (FAPlacePoint *savedOriginPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed) {
    [self processPoint:destinationPlacePoint completionHandler:^void (FAPlacePoint *savedDestinationPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed) {

        // Everything is finished.  Do something with savedOriginPP and savedDestinationPP

    }];
}];