今天,当我试图"概括"我的'CoreData导入操作'时,我遇到了一个奇怪的问题.似乎如果我创建NSOperation的泛型子类,main()则不会调用func.
简单的例子:
class MyOperation<T: NSObject>: NSOperation {
override func main() {
println("My operation main was called")
}
}
Run Code Online (Sandbox Code Playgroud)
如果您创建此类的实例并将其添加到operationQueue您将看到它main()实际上没有被调用.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.operationQueue = NSOperationQueue()
let operation = MyOperation<NSString>()
self.operationQueue!.addOperation(operation)
}
Run Code Online (Sandbox Code Playgroud)
操作简单地从过境ready到executing和finished状态,而无需调用main().
如果我<T: NSObject>从MyOperation类中删除泛型注释,它将正常工作.
这怎么可能?我在这里错过了什么吗?
我正在处理一项任务(仅限iOS5 +),涉及从服务器下载数千张图像.图像属于某些类别,每个类别可以有数百个图像.我需要做的是: -
1)如果应用程序处于活动状态,请确保应用程序在后台下载任何丢失的图像(即使用户正在浏览应用程序中与照片无关的其他某些区域).
2)当用户点击照片类别时,必须将该类别中的图像作为高优先级下载,因为那些是需要立即可见的图像.
所有上述操作仅在图像尚未脱机可用时才会发生.下载后,图像将从本地存储中使用.
要解决这个问题,我使用的逻辑是: -
1)在AppDelegate.m中applicationDidBecomeActive,我开始下载任何丢失的图像.为此,我进行了核心数据查询,找出缺少的图像,并开始在具有BACKGROUND优先级的线程中下载它们.像这样: -
dispatch_queue_t imageDownloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(imageDownloadQueue, ^{
[DataDownloader downloadMissingImages];
});
dispatch_release(imageDownloadQueue);
Run Code Online (Sandbox Code Playgroud)
该downloadMissingImages代码如下所示: -
NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
downloadQueue.maxConcurrentOperationCount = 20;
for(MyImage *img in matches)
{
NSURLRequest *request = [NSURLRequest requestWithURL:img.photoUrl];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {
[MyImage imageFromAPI:image inManagedObjectContext:document.managedObjectContext];
NSLog(@"Successfully downloaded image for %@", img.title);
}];
[downloadQueue addOperation:operation];
}
Run Code Online (Sandbox Code Playgroud)
这可行,但它会阻止主UI和应用程序崩溃一段时间后.这是我尝试下载大约700张图片的时候.随着更多的图像,它肯定会崩溃.
2)当用户点击某个类别时,我需要先下载这些图像,因为它们必须立即显示给用户.我不知道如何中断missImages调用并告诉它开始在其他人之前下载某些图像.
所以,基本上,我需要在后台下载所有丢失的图像,但如果用户正在浏览照片类别,那些图像必须在下载队列中具有高优先级.
我不知道如何有效地工作.有什么想法吗?
崩溃日志看起来像这样
PAPP(36373,0xb065f000) malloc: *** mmap(size=16777216) failed (error code=12)
*** …Run Code Online (Sandbox Code Playgroud) 我一直在调查,NSProgress但发现现有的文档,课程参考和教程缺乏.我主要想知道我的NSProgress是否适用于我的用例.类引用文档或者引用suboperations或者subtasks,我可能会弄错,但我解释suboperations为NSOperation管理一组其他的情况NSOperations.我的用例的一个例子如下:
Upload All Items in Group为存在的每个组创建操作.NSOperationQueue.Upload All Items in Group操作都将Upload Item为其组中的每个项目创建一个操作.这些都被添加到NSOperationQueue由操作管理的中.我本来希望NSProgress支持这一点,并允许我将进度从嵌套操作(Upload Item操作)传播到父操作,然后最终传播到主线程和UI.但是我很难实现这一点,似乎NSProgress对于在一个后台线程上执行所有代码的长操作意味着更多,但是有单独的"部分"可以很容易地确定何时进行了进展,如果这是在这种情况下,使用该术语suboperation有点误导,因为它会让人联想到嵌套的使用NSOperations.
感谢您提供的任何帮助,如果需要其他详细信息,请与我们联系.
multithreading objective-c nsoperation nsoperationqueue nsprogress
我正在使用NSOperation和NSOperationQueue执行一系列操作,所有这些操作都相互依赖(2对1,3对2等等).我在创建操作后设置依赖项.我在队列完成时遇到问题:程序在代码的_release部分崩溃,显然是在NSOperations被释放时.请注意,它们最后都是由队列释放的,因为它只是在最后一个依赖于最后一个的时间之后,这取决于等等......它们可以被释放.如果我删除任何依赖项,代码运行正常.如果我将waitUntilFinished:改为NO,它会崩溃,如果是,则不会.
我已将问题隔离到以下代码,该代码不使用任何自定义类.默认情况下,NSOperation是一个绝对没有任何内容的类.然而,当所有操作完成时,这仍然会崩溃.因此,看来我没有正确使用NSOperationQueue,但看不出有什么问题.我在10.9上运行,我注意到一般来说Maverick 10.9对这些问题比10.8更敏感.
我使用Menu项从主线程中调用此方法:
- (void) testOperations:(id)object
{
NSOperationQueue* queue = [ [ NSOperationQueue alloc ] init ];
NSMutableArray* array = [ NSMutableArray array ];
for ( int i = 0; i < 10000; i++)
[ array addObject: [[[ NSOperation alloc ] init ] autorelease ] ];
for ( int i = 1; i < [ array count ]; i++)
[[ array objectAtIndex:i ] addDependency:[array objectAtIndex:i-1]]; // remove this and no crash
[ queue addOperations: …Run Code Online (Sandbox Code Playgroud) 我有时在我的应用程序中遇到以下崩溃:
Crashed Thread: 4 Dispatch queue: NSOperationQueue 0x7fc2d96277c0 :: NSOperation 0x7fc2d9704440 (QOS: UTILITY)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000007fc2d968980
Exception Note: EXC_CORPSE_NOTIFY
Thread 4 Crashed:: Dispatch queue: NSOperationQueue 0x7fc2d96277c0 :: NSOperation 0x7fc2d9704440 (QOS: UTILITY)
0 libobjc.A.dylib 0x00007fff86bd720f objc_release + 31
1 libobjc.A.dylib 0x00007fff86bdeb81 object_cxxDestructFromClass(objc_object*, objc_class*) + 127
2 libobjc.A.dylib 0x00007fff86bd7383 objc_destructInstance + 116
3 libobjc.A.dylib 0x00007fff86bd72e5 object_dispose + 22
4 libobjc.A.dylib 0x00007fff86bdd224 objc_object::sidetable_release(bool) + 242
5 com.apple.CoreFoundation 0x00007fff9198d2dd -[__NSArrayM dealloc] + 205
6 libobjc.A.dylib 0x00007fff86bdd224 objc_object::sidetable_release(bool) + …Run Code Online (Sandbox Code Playgroud) 我有一个Operation子类和操作队列,maxConcurrentOperationCount = 1.
这按顺序执行我的操作,我添加它们是好的,但现在我需要等到所有操作完成后再运行另一个进程.
我正在尝试使用通知组,但是一旦将操作添加到队列中,这就会在for循环中运行,通知组将触发..如何在运行另一个进程之前等待所有操作离开队列?
for (index, _) in self.packArray.enumerated() {
myGroup.enter()
let myArrayOperation = ArrayOperation(collection: self.outerCollectionView, id: self.packArray[index].id, count: index)
myArrayOperation.name = self.packArray[index].id
downloadQueue.addOperation(myArrayOperation)
myGroup.leave()
}
myGroup.notify(queue: .main) {
// do stuff here
}
Run Code Online (Sandbox Code Playgroud) 我有NSOperationQueue一些NSOperations(NSInvocationOperations特别是).此操作会进行一些计算并相应地(当然,通过performSelectorOnMainThread:...)更改UI元素的状态,通常使用动画.
我的UI有UINavigationViewController和一些用于导航到另一个视图的按钮.因此,用户可以保留当前视图,而计算/动画仍在进行中.我需要的是以某种方式停止这一点,直到用户回到当前视图.
我找到的唯一解决方案是创建一些线程安全的布尔标志 - 并在所有线程中检查它(类似于:while!flag sleep_for_some_time;).还有更好的东西吗?
我有一个项目,使用后台下载图像NSOperationQueue.它一直在使用IOS 4.3的设备上工作.但是,如果我使用基本sdk 4.3或5构建应用程序并使用IOS5在设备上运行应用程序,则应用程序崩溃.启动应用程序时,它会将NSOperation对象添加到队列中以下载图像.如果在我之间按下后退按钮,我取消它NSOperation并且它崩溃并在控制台上显示以下跟踪:
#0 0x004727b7 in ____NSOQSchedule_block_invoke_0 () #1 0x026a5618 in _dispatch_call_block_and_release () #2 0x026a7a10 in _dispatch_worker_thread2 () #3 0x974bb781 in _pthread_wqthread () #4 0x974bb5c6 in start_wqthread ()
并打印"ResourceLoadOperation isFinished = YES,而不是由它所在的队列启动"如果我评论取消方法调用,应用程序不会崩溃.NSOperationIOS5 的更改是否有任何更新?
我正面临着我的应用程序的设计问题.
基本上,以下是我在我的应用程序中要做的事情.
单个任务是这样的:
可能会同时执行许多任务.
一个任务中的步骤显然是ordered(即,没有第2步下载json,第3步不能继续),但它们也可以discrete.我的意思是,例如,task2的第4步可以在task1的第3步之前执行(如果task2的下载速度比task1的更快)
任务有优先事项.用户可以启动具有更高优先级的任务,因此将尝试在所有其他任务之前执行所有任务的步骤.
我希望UI能够尽可能地响应.
所以我打算创建一个优先级最低的NSThread.
我在该线程中放置了一个自定义优先级事件队列.任务的每一步都成为一个事件(工作单位).因此,例如,下载json的步骤1成为事件.下载后,该事件会为步骤3生成另一个事件并将其放入队列中.每个事件都有自己的优先级设置.
现在我看到这篇文章:并发和应用程序设计.Apple建议我们Move Away from Threads使用GCD或NSOperation.
我发现这NSOperation与我的草稿设计相匹配.但我有以下问题:
谢谢
请告诉我如何在C++中实现NSOperation和NSOperationQueue功能.
nsoperationqueue ×10
nsoperation ×7
objective-c ×5
iphone ×2
swift ×2
afnetworking ×1
c++ ×1
generics ×1
ios ×1
ios5 ×1
nsprogress ×1
nsthread ×1