我想知道如何正确执行以下操作:我有一个返回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}}。
如何在不必使线程阻塞等待/循环的情况下完成此操作?
感谢。
答案 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")
}