2013-04-05 21 views
0

如何才能將此方法轉換爲一個無法完成的塊,直到'請求startWithCompletionHandler'塊完成其請求並在其自己的塊中執行代碼?如何嵌套塊,以便它們同時結束

我有一系列塊需要按順序調用,但它們都需要代碼發送它們的請求。試圖找到一個乾淨的方式來完成任務。

+(void)???????? ^block() 
{ 
    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey]; 
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 
     .... 
    }]; 
} 

ADDED INFO:是的,我要外功能要等到內部功能齊全

感謝。

回答

1

這取決於你的意思。給出你的示例代碼,看起來你想讓你的函數在嵌套塊完成時調用一個塊。所以你想要的東西是這樣的:

+ (void)doMyThingWithBlock:(void(^)(void))block 
{ 
    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey]; 
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 

     // do whatever you want with the connection ... 

     if (block) block(); 

    }]; 
} 

另一方面,也許你希望外部函數等待嵌套塊返回前完成。在這種情況下,這有點複雜。您需要使用的鎖等待塊來完成,像這樣:

#define kMyThingNotDone 0 
#define kMyThingDone 1 

+ (void)doMyThingAndWait 
{ 
    NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:kMyThingNotDone]; 

    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey]; 
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 

     // do whatever you want with the connection ... 

     [lock lock]; 
     [lock unlockWithCondition:kMyThingDone]; 

    }]; 

    [lock lockWhenCondition:kMyThingDone]; 
    [lock unlock]; 
} 

被警告 - 你不想做這個主線程上,否則你會鎖定用戶界面。您還必須確保請求不會等待您調用此線程的任何事情發生,否則最終會導致死鎖。

-1

如果您的唯一要求是按順序執行請求,並且FBRequest不會爲您執行(我不熟悉API),則可以選擇將這些調用包裝在串行隊列中。

dispatch_queue_t mySerialQueue = dispatch_queue_create("com.mycompany.serializedrequests", NULL); 
dispatch_async(mySerialQueue, ^{ 
    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey]; 
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 
    .... 
    }]; 
}); 
-1

使用類似於facebook的API,您永遠不會知道請求將花費多長時間(網絡條件/負載在其端點上發生更改/ ...),所以我不會使用任何鎖定/等待的線程。

如果傳遞到您的方法的方塊(其可以封裝其它塊以及將要執行順序):

+(void) getFacebookDataWithCompletion:(void (^)(<some parameters))completion { 

    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey]; 
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 

     if (!error) 
     { 
      //Do your thing with the facebook result (update user info, ....) 
     } 
     if (completion) 
     { 
      //Now that you have what you need from fb run your block(s) 
      completion(<params>); 
     } 

    }]; 
    } 
相關問題