我相信我的用例相当普遍,但是我找不到任何可以使我100%确定自己在做什么的文档。任何指针表示赞赏。
在我的应用程序中的某个时刻,我开始下载对象。之后,用户可以单击一个按钮。如果对象已完成下载,我想执行一些代码。否则,我要等到对象下载完毕并执行相同的代码。如果用户未单击该按钮,则我什么也不想做。下载的对象丢失。
我的基本想法是执行以下操作:
NSObject *myObj = nil;
- (void)download {
[self downloadObj:^(NSObject *obj){
myObj = obj;
}];
}
- (void)buttonClicked {
waitOrExecuteDirectly:^{
// Some code with myObj
}
}
当然,第一个问题是“我如何等待?”
所以我尝试了
- (void)buttonClicked {
if(myObj) {
// Some code
} else {
// Wait then do the exact same code
}
}
但是我认为棘手的问题是“如果在计算“ if”之后并且在输入“ else”块之前对象完成下载,会发生什么?”。
我试图将下载文件封装在中NSOperation
并使用该completionBlock
属性。但是,如果在设置回调时该操作已经完成,则永不调用completionBlock。我不想在“下载”方法中设置回调,因为用户可能不会单击按钮。
是否有内置机制允许我根据任务状态为将等待或直接执行的任务提供完成回调?如果没有,那么由我自己做的最佳实践是什么?NSLock
设置和阅读时使用myObj
?
我认为您不应该在主线程上等待,因为那样会阻塞整个用户界面。我的方法是这样的:
typedef MyOperation void (^)(NSData * myData);
...
@private MyOperation _operationWhenDownloadFinished; // instance variable
@private NSData * _data
...
-(void)buttonPressed{
[self waitAndPerformOperation:^(NSData * myData){ ... }];
}
-(void)waitAndPerformOperation:(MyOperation)operation{
if(_data != nil){
operation(myData);
_operationWhenDownloadFinished = nil;
}else{
_operationWhenDownloadFinished = operation;
}
}
...
-(void)downloadFinished:(NSData*)downloadedData{ // this is called on the main thread, e.g. by an NSURLConnection delegate
_data = downloadedData;
if(_operationWhenDownloadFinished != nil){
[self waitAndPerformOperation:_operationWhenDownloadFinished];
}
}
由于按下按钮和downloadFinished委托回调都发生在主线程上,因此我们可以毫不费力地避免任何竞争情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句