Returning method object from inside block

痞子三分冷 提交于 2019-12-25 05:06:47

问题


I am wondering how to do the following correctly: I have a method that is to return an NSData object. It gets the NSData object from a UIDocument. The NSData object can get large, so I want to make sure it is fully loaded before the response starts. I would therefore like to return the value of the method from within the block itself. So something like this:

- (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
    }
  }];
}

This causes an error because the return apparently refers to the block's return.

How can I accomplish this without having to make a thread blocking wait/while loop?

Thanks.


回答1:


You can't. Embrace the fact that what you're trying to do is asynchronous and add a completion block parameter to your getMyData method which is called when the inner completion handler is called. (And remove the return from the method signature):

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

The same problem exists in swift and you can add a similar completion block:

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



回答2:


The open method is asynchronous which is why you have to provide a block to be run when the open is completed. You need to copy this and make your method also receive a block of code that you will execute when the open is finished.

You should also pass through the success argument of the call you are wrapping or create an error, you need to do this so that the calling code can take the right action.

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



回答3:


Following Are method how to declare method with completionHandler:

Objective-C

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

Swift-3

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


来源:https://stackoverflow.com/questions/23989205/how-to-return-rest-kit-response-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!