从内部块返回方法对象

时间:2014-03-08 10:04:30

标签: ios objective-c block uidocument completionhandler

我想知道如何正确执行以下操作:我有一个返回NSData对象的方法。它从NSData获取UIDocument对象。 NSData对象可能变大,所以我想确保在响应开始之前它已完全加载。因此,我想从块本身返回方法的值。所以像这样:

- (NSData*)getMyData {
  MyUIDocument *doc = [[MyUIDocument alloc] initWithFileURL:fileURL];
  [doc openWithCompletionHandler:^(BOOL success) {

    if (success) {
      return doc.myResponseData; // this is to be the return for the method not the block
    }
  }];
}

这会导致错误,因为return显然是指block的{​​{1}}。

如何在不必使线程阻塞等待/循环的情况下完成此操作?

感谢。

3 个答案:

答案 0 :(得分:12)

你做不到。接受这样一个事实,即你要做的是异步并向你的getMyData方法添加一个完成块参数,该方法在调用内部完成处理程序时调用。 (并从方法签名中删除return):

- (void)getMyDataWithCompletion:(void(^)(NSData *data))completion {
    MyUIDocument *doc = [[MyUIDocument alloc] initWithFileURL:fileURL];
    [doc openWithCompletionHandler:^(BOOL success) {
        completion((success ? doc.myResponseData : nil));
    }];
}

swift中存在同样的问题,您可以添加类似的完成块:

func getMyData(completion: ((data: NSData?) -> Void) {
    data = ...
    completion(data)
}

答案 1 :(得分:0)

open方法是异步的,这就是为什么你必须在open完成时提供一个块来运行。您需要复制它并使您的方法还接收一个代码块,您将在打开完成时执行该代码块。

您还应该传递正在包装的调用的成功参数或创建错误,您需要这样做,以便调用代码可以采取正确的操作。

- (void)getMyDataWithCompletion:(void(^)(NSData *data, BOOL success))completion
{
  MyUIDocument *doc = [[MyUIDocument alloc] initWithFileURL:fileURL];
  [doc openWithCompletionHandler:^(BOOL success) {
    completion(doc.myResponseData, success);
  }];
}

答案 2 :(得分:0)

以下Are方法如何使用completionHandler声明方法:

<强>目标C

- (void)getMyDataWithCompletionHandler:(void(^)(NSString *str))completionHandler
{
    completionHandler(@"Test");
}

<强>夫特-3

func showDatePicker(superc: UIViewController, completionHandler:@escaping (String) -> Void)  {
            completionHandler("Test")
}