ios – 使用[NSThread sleep:]解决死锁问题

ios – 使用[NSThread sleep:]解决死锁问题,第1张

概述我只是“解决”了似乎是死锁或同步问题: [NSThread sleepForTimeInterval:0.1]; 在一个应用程序中,将来自IPOD库的MPMediaItem(音乐/图像)属性引用附加到对象实例,并通过CoreData对这些对象进行反向存储.我的兴趣是要准确了解发生了什么,以及在这种情况下最佳做法是什么.开始: 每次复制此内容的方法如下: >用户创建一个新项目. doc = [[UI 我只是“解决”了似乎是死锁或同步问题:

[NSThread sleepForTimeInterval:0.1];

在一个应用程序中,将来自IPOD库的MPMediaItem(音乐/图像)属性引用附加到对象实例,并通过CoreData对这些对象进行反向存储.我的兴趣是要准确了解发生了什么,以及在这种情况下最佳做法是什么.开始:

每次复制此内容的方法如下:

>用户创建一个新项目.

doc = [[UIManageddocument alloc] initWithfileURL:docURL];if (![[NSfileManager defaultManager] fileExistsAtPath:[docURL path]]) {    [doc savetoURL:docURL forSaveOperation:UIdocumentSaveForCreating completionHandler:^(BOol success) {    if (success) {        completionBlock(doc);    }    else {        DLog(@"Failed document creation: %@",doc.localizedname);    }}];

>稍后,managedobjectContext用于关联对象实例并对CoreData模型进行水合

TheProject *theProject = [TheProject projectWithInfo:theProjectInfo                              inManagedobjectContext:doc.managedobjectContext];

>用户稍后创建“CustomAction”对象,向其添加“ChElement”并将“MusicElement”与ChElement相关联. (这些是CoreData模型对象的假名). MusicElement通过IPOD库添加.

#@R_419_5552@ PLAYER [MPMusicPlayerController iPodMusicPlayer]

>用户保存此项目,然后切换到已创建一个CustomAction对象的现有项目,其中包含ChElement和MusicElement.
>用户从tableVIEw中选择该ChElement并导航到detailVIEw.
当导航离开ChElementTVC(类似于Apple文档中的CoreData tableVIEwController类的子类)时,这是必需的:

- (voID)vIEwWilldisappear:(BOol)animated{    [super vIEwWilldisappear:animated];    self.fetchedResultsController.delegate = nil;}

>在详细信息视图中,用户更改ChElement对象的属性并保存项目. detailVIEw调用其委托(ChElementTVC)来进行保存.保存是保存NSManagedobject的UIManageddocument实例.

#@R_419_5552@ SAVEDOC(__DOC__) [ProjectdocumentHelper saveProjectdocument:__DOC__]// Delegate- (voID)chAddElementDetailVIEwController:(ChDetailVIEwController *)sender dIDPressSavebutton:(Nsstring *)message{    SAVEDOC(THE_CURRENT_PROJECT_document);    [self.navigationController popVIEwControllerAnimated:YES]; }// Helper Class+ (voID)saveProjectdocument:(UIManageddocument *)targetdocument{    NSManagedobjectContext *moc = targetdocument.managedobjectContext;    [moc performBlockAnDWait:^{        DLog(@" Process Pending Changes before saving : %@,Context = %@",targetdocument.description,moc);        [moc processpendingChanges];        [targetdocument savetoURL:targetdocument.fileURL forSaveOperation:UIdocumentSaveForOverwriting completionHandler:NulL];    }];}

>由于委托(ChElementTVC)从导航堆栈d出detailVIEw,
调用其vIEwWillAppear,并恢复fetchedResultsController.delegate.

- (voID)vIEwWillAppear:(BOol)animated{    [super vIEwWillAppear:animated];    if (!self.fetchedResultsController.delegate) {        DLog(@"Sleep Now %@",self);        //http://mobiledevelopertips.com/core-services/sleep-pause-or-block-a-thread.HTML       [NSThread sleepForTimeInterval:0.1];       DLog(@"Wake up %@",self);       [self fetchedResultsControllerWithPredicate:_savedPredicate]; // App Hangs Here ... This is sending messages to CoreData objects.       [self.tableVIEw reloadData];}

没有[NSThread sleepForTimeInterval:0.1];该应用程序挂起.当我通过Xcode发送SIGINT时,我得到调试器并显示以下内容:

(lldb)bt

* thread #1: tID = 0x1c03,0x30e06054 libsystem_kernel.dylib semaphore_wait_trap + 8,stop reason = signal SIGINT    frame #0: 0x30e06054 libsystem_kernel.dylib semaphore_wait_trap + 8    frame #1: 0x32c614f4 libdispatch.dylib _dispatch_thread_semaphore_wait$VARIANT$mp + 12       frame #2: 0x32c5f6a4 libdispatch.dylib _dispatch_barrIEr_sync_f_slow + 92       frame #3: 0x32c5f61e libdispatch.dylib dispatch_barrIEr_sync_f$VARIANT$mp + 22    frame #4: 0x32c5f266 libdispatch.dylib dispatch_sync_f$VARIANT$mp + 18    frame #5: 0x35860564 CoreData _perform + 160

(lldb)帧选择5

frame #5: 0x35860564 CoreData _perform + 160    CoreData _perform + 160:    -> 0x35860564:  add    sp,#12       0x35860566:  pop    {r4,r5,r7,pc}    CoreData -[NSManagedobjectContext(_nestedContextSupport) executeRequest:withContext:error:]:       0x35860568:  push   {r4,r6,lr}       0x3586056a:  add    r7,sp,#12

(lldb)反汇编-f

CoreData _perform:        0x358604c4:  push   {r4,lr}    ... snipped ...        0x35860560:  blx    0x35938bf4                ; symbol stub for: dispatch_sync_f    -> 0x35860564:  add    sp,pc}

另一种解决方法是可行的.在 – [ChElementTVC vIEwDIDAppear:]中编码fetchedResultsController.delegate恢复也有效地延迟了主队列上的此设置.

另一种解决方法是在项目保存完成后在完成块中执行导航d出:

#@R_419_5552@ SAVEDOCWITHCOMPLETION(__DOC__,__COMPLETION_BLOCK__)[ProjectdocumentHelper saveProjectdocument:__DOC__ completionHandler:__COMPLETION_BLOCK__]    voID (^completionBlock)(BOol) = ^(BOol success) {        [self.navigationController popVIEwControllerAnimated:YES];    };    SAVEDOCWITHCOMPLETION(THE_CURRENT_PROJECT_document,completionBlock);

我认为保存 *** 作在后台与主队列上的委托恢复同时运行,但我不知道如何检查/证明/反驳该理论.

那么,有人可以解释发生了什么,在这种情况下最好的做法是什么?此外,赞赏研究参考.

解决方法 我最终实现了第三种方法,即使用完成块保存文档以序列化与CoreData存储交互的事务. 总结

以上是内存溢出为你收集整理的ios – 使用[NSThread sleep:]解决死锁问题全部内容,希望文章能够帮你解决ios – 使用[NSThread sleep:]解决死锁问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/999373.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存