如何将此方法转换为一个块,直到'request startWithCompletionHandler'块完成它的请求并且代码在自己的块中完成后才能完成?
我需要按顺序调用一系列块,但它们都需要代码才能发送请求。试图找到一种干净的方法来完成任务。
+(void)???????? ^block()
{
FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
....
}];
}
ADDED INFO:是的,我希望外部函数等到内部函数完成
感谢。
答案 0 :(得分: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 :(得分:-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) {
....
}];
});
答案 2 :(得分:-1)
使用像facebook那样的API,你永远不会知道请求需要多长时间(网络条件/负载的变化/ ....)所以我不会使用任何线程锁定/等待它。 / p>
如果你传递给你的方法一个块(它可以封装其他块以及顺序执行):
+(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>);
}
}];
}