从块内部返回方法对象

我想知道如何正确地做到以下几点:我有一个方法是返回一个NSData对象。 它从UIDocument获取NSData对象。 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显然是指blockreturn

我怎样才能做到这一点,而不必做一个线程阻塞等待/ while循环?

谢谢。

你不能。 拥抱这样一个事实,即你正在尝试做的是asynchronous的,并且在你的getMyData方法中添加了一个完成块参数, 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) } 

open方法是asynchronous的,这就是为什么当打开完成时你必须提供一个块来运行。 你需要复制这个,并让你的方法也收到一个代码块,你将在打开完成时执行。

您还应该通过您正在包装的调用的成功参数或创build一个错误,您需要这样做,以便调用代码可以采取正确的行动。

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

以下是方法如何用completionHandler声明方法:

Objective-C的

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

斯威夫特-3

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