我有一个Objective C中的异步方法,你传递一个完成处理程序。是否有可能避免写这个块调用代码'倒退'?
我希望有条件地在两个不同的对象上运行这个方法两次,然后处理结果。
我可以找到做这项工作的唯一方法就是按照下面的方式写代码'向后'。
这意味着我的主要架构失败。有没有更好的办法?
defines.h
#define BLOCK_SAFE_RUN(block, ...) block ? block(__VA_ARGS__) : nil
myController.h
// Code executes in the order (0),(1),(2),(3),(4) - see comments
// (0) Create the origin completion handler
void (^originCompletionHandler)(FAPlacePoint *, BOOL, BOOL) = ^void (FAPlacePoint *savedOriginPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed)
{
// (2) Create the destination completion handler
void (^destinationCompletionHandler)(FAPlacePoint *, BOOL, BOOL) = ^void (FAPlacePoint *savedDestinationPP, BOOL geoCodeDidSucceed, BOOL saveDidSucceed)
{
// (4)
// Everything is finished. Do something with savedOriginPP and savedDestinationPP
};
// (3) Conditionally run the geocode method with the dest point then call the destination completion handler
if (destinationPlacePoint.currentLocation)
[self reverseGeocodeThenSavePlacePoint:destinationPlacePoint completion:destinationCompletionHandler];
else
{
FAPlacePoint * pp = [self storePlacePoint:destinationPlacePoint];
BLOCK_SAFE_RUN(destinationCompletionHandler, pp, YES, YES);
}
};
// (1) Conditionally run the geocode method with the origin point then call the origin completion handler
if (originPlacePoint.currentLocation)
[self reverseGeocodeThenSavePlacePoint:originPlacePoint completion:originCompletionHandler];
else
{
FAPlacePoint * pp = [self storePlacePoint:originPlacePoint];
BLOCK_SAFE_RUN(originCompletionHandler, pp, YES, YES);
}
我不知道你有什么想法,你必须在使用它之前定义一个块。任何采用block参数的方法都可以使用与调用内联的块进行定义。所以要运行一系列的程序段才能嵌套。 – 2014-12-04 21:44:51
@jshier更确切地说,你必须定义一个block *变量*,然后才能使用它来调用该块。当然,你可以使用块本身作为参数,但是你会注意到OP想要从两个不同的地方调用同一个块。 Ken Thomases的回答有助于避免在这种特殊情况下的需要。但是,一般来说,如果要在多个地方使用同一个块,则需要将其分配给一个变量,而在使用该变量调用块之前,您显然需要这样做。 – Caleb 2014-12-04 22:26:26
我非常感谢你的回答。我给予Ken Thomases的答案的唯一原因是,严格地说,他提供了解决所述问题的代码。 – 2014-12-17 17:07:49