我有一個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