我正在学习iOS的并发编程.到目前为止,我已经读过NSOperation/NSOperationQueue和GCD.使用NSOperationQueueover 的原因是什么GCD,反之亦然?
听起来像是两者,GCD并从用户那里NSOperationQueue抽象出明确的创造NSThreads.然而这两种方法之间的关系对我来说并不清楚,所以任何反馈都要赞赏!
concurrency nsoperation nsoperationqueue grand-central-dispatch ios
我希望for循环向firebase发送一堆网络请求,然后在方法完成执行后将数据传递给新的视图控制器.这是我的代码:
var datesArray = [String: AnyObject]()
for key in locationsArray {
let ref = Firebase(url: "http://myfirebase.com/" + "\(key.0)")
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
datesArray["\(key.0)"] = snapshot.value
})
}
// Segue to new view controller here and pass datesArray once it is complete
Run Code Online (Sandbox Code Playgroud)
我有几个问题.首先,我如何等待for循环完成并且所有网络请求都已完成?我无法修改observeSingleEventOfType函数,它是firebase SDK的一部分.另外,我是否会通过尝试从for循环的不同迭代中访问datesArray来创建某种竞争条件(希望这是有道理的)?我一直在阅读有关GCD和NSOperation的内容,但我有点失落,因为这是我构建的第一个应用程序.
注意:Locations数组是一个包含我需要在firebase中访问的键的数组.此外,重要的是异步触发网络请求.我只想等到所有异步请求完成后再将datesArray传递给下一个视图控制器.
NSOperationQueue有waitUntilAllOperationsAreFinished,但我不想同步等待它.我只想在队列完成时隐藏UI中的进度指示器.
实现这一目标的最佳方法是什么?
我不能发送来自我NSOperation的通知,因为我不知道哪一个会是最后一个,并且[queue operations]在收到通知时可能不会是空的(或者更糟糕的是 - 重新填充).
我必须在我的应用程序中执行一系列下载和数据库写入操作.我正在使用NSOperation和NSOperationQueue相同的.
这是应用场景:
如上所述,我NSOperation为每项任务定义了一个.在第一种情况下(Task1),我向服务器发送请求以获取所有邮政编码.将在该会议中的代表NSOperation接收数据.然后将该数据写入数据库.数据库操作在不同的类中定义.从NSOperation类I开始调用数据库类中定义的write函数.
我的问题是数据库写操作是在主线程还是后台线程中发生的?正如我在其中调用它一样, NSOperation我期望它在不同的线程(Not MainThread)中运行NSOperation.有人可以在处理NSOperation和解释这个场景时解释NSOperationQueue.
我正在尝试构建一个批量图像下载器,可以将图像动态添加到队列中进行下载,我可以找到进度以及何时完成下载.
通过我的阅读,似乎NSOperationQueue对于队列功能和NSURLSession网络功能似乎是我最好的选择,但我很困惑如何使用这两个串联.
我知道我想补充的情况下,NSOperation在NSOperationQueue他们得到排队.似乎我创建了一个下载任务NSURLSessionDownloadTask,如果我需要多个任务,我会创建多个任务,但我不确定如何将两者放在一起.
NSURLSessionDownloadTaskDelegate 似乎拥有下载进度和完成通知所需的所有信息,但我还需要能够停止特定下载,停止所有下载,并处理从下载中获取的数据.
我无法找到关于如何子类化为NSOperation并发以及支持取消的良好文档.我阅读了Apple文档,但我无法找到"官方"示例.
这是我的源代码:
@synthesize isExecuting = _isExecuting;
@synthesize isFinished = _isFinished;
@synthesize isCancelled = _isCancelled;
- (BOOL)isConcurrent
{
return YES;
}
- (void)start
{
/* WHY SHOULD I PUT THIS ?
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}
*/
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
if (_isCancelled == YES)
{
NSLog(@"** OPERATION CANCELED **");
}
else
{
NSLog(@"Operation started.");
sleep(1);
[self finish];
}
}
- (void)finish
{
NSLog(@"operationfinished.");
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO; …Run Code Online (Sandbox Code Playgroud) 我有一个长时间运行的循环,我想在后台运行一个NSOperation.我想用一个块:
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
while(/* not canceled*/){
//do something...
}
}];
Run Code Online (Sandbox Code Playgroud)
问题是,如何检查它是否被取消.该块不带任何参数,并且operation在块被捕获时为零.有没有办法取消块操作?
我一直在寻找一些具体的场景,NSOperation以确定iPhone 何时是应用程序中使用的理想工具.据我所知,这是编写自己的threaded代码的包装器.我还没有看到任何使用它的Apple演示应用程序,我想知道我是否错过了一个很棒的工具而不是使用它NSThread.
这里的理想解决方案是描述用例场景NSOperation以及如何使用它来解决您的问题.
我遇到以下警告问题:
CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯.
我正在使用NSOperation对象来执行一些计算,一旦完成,它会将消息发送回AppDelegate,然后隐藏进度条并取消隐藏某些按钮.如果我将消息注释回AppDelegate,则警告消失,但进度条显然仍然可见且动画.
我正在使用xCode 4.4.1和OSX 10.8.1,但是,当我在OSX 10.7.4上使用相同版本的xCode编译和运行代码时,我没有收到警告,代码按预期运行.
设置CA_DEBUG_TRANSACTIONS = 1环境变量会将回溯显示为来自AppDelegate中的NSControl setEnabled消息.
答案可能是盯着我看,但也许我喝的咖啡太多了!
我从Facebook Connect获取一些数据(使用FBConnect Objective-C 2.0框架),我正在NSOperation中完成所有这些工作.它在NSOperation中,因为我还运行了其他几个操作,这就是其中之一.
问题是所有FBConnect调用都是异步的.因此,NSOperation的主要方法快速完成,操作标记为已完成.
有办法克服这个问题吗?看来FBConnect中没有同步选项!
非常感谢,
麦克风
nsoperation ×10
iphone ×4
asynchronous ×3
ios ×3
objective-c ×3
cocoa-touch ×1
concurrency ×1
fbconnect ×1
nsurlsession ×1
queue ×1
swift ×1