PDFDocument removePageAtIndex:在更新到Mac OS X 10.11时不工作 [英] PDFDocument removePageAtIndex: is not working when updated to Mac OS X 10.11

查看:282
本文介绍了PDFDocument removePageAtIndex:在更新到Mac OS X 10.11时不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在使用PDFKit框架应用程序冻结在代码行

 可能的应用程序PDFViewer.When我正在删除PDFDocument中的一个页面。 [[self pdfDocument] removePageAtIndex:0]; //可以看到这个问题只有在Mac OS X 10.11 

Mac OS X 10.10



我阅读所有相关的苹果文档,但我还没有得到任何解决方案。



这里是backtrace:

  *线程#1:tid = 0x85e1,0x00007fff92571f5e libsystem_kernel.dylib `__psynch_cvwait + 10,queue ='com.apple.main-thread',stop reason = signal SIGTERM 
frame#0:0x00007fff92571f5e libsystem_kernel.dylib `__psynch_cvwait + 10
frame#1:0x00000001006c05f7 libsystem_pthread.dylib `_pthread_cond_wait + 767
帧#2:0x00007fff904c6e32 Foundation` - [__ NSOperationInternal _waitUntilFinished:] + 131
帧#3:0x00007fff904921fa Foundation`- [NSOperationQueue waitUntilAllOperationsAreFinished] + 254
*帧#4: 0x000000010017efe1 Neat`- [NRMPDFCoordinator waitUntilAllOperationsAreFinished](自= 0x0000608000ad3be0,_cmd = 0x00007fff8877e285)+ 145在NRMPDFCoordinator.m:1362
帧#5:0x00000001000109cf Neat`- [NRMItemEditorDocument saveDocumentWithDelegate:didSaveSelector:contextInfo:](自= 0x000060000094a190 ,_cmd = 0x00007fff88777581,委托= 0x0000000000000000,didSaveSelector = 0x0000000000000000,contextInfo = 0x0000000000000000)+ 1151在NRMItemEditorDocument.m:325
帧#6:0x000000010001018a Neat`- [NRMItemEditorDocument saveDocument:(自我= 0x000060000094a190,_cmd = 0x00007fff8874cbb4 ,发件人= 0x00006080003a8b20)+ 58在NRMItemEditorDocument.m:234
帧#7:0x0000000100013bef Neat`- [NRMItemEditorWindowController saveAndClose:(自我= 0x00006080003a8b20,_cmd = 0x00000001002cf2d2,发件人= 0x000060000094a5b0)+ 95在NRMItemEditorWindowController.m: 244
帧#8:0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
帧#9:0x00007fff87fc79b5 AppKit`- [的NSApplication sendAction::从:] + 460
帧#10:0x00007fff87fd9bb2了AppKit ` - [NSControl sendAction:to:] + 86
frame#11:0x00007fff87fd9adc AppKit`__26- [NSCell _sendActionFrom:] _ block_invoke + 131
frame#12:0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
帧#13:0x00007fff87fd9a39 AppKit`- [的NSCell _sendActionFrom:] + 144
帧#14:0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
帧#15:0x00007fff87fd805e AppKit`- [的NSCell tr​​ackMouse:inRect :ofView:untilMouseUp:] + 2693
frame#16:0x00007fff88020d1c AppKit`- [NSButtonCell tr​​ackMouse:inRect:ofView:untilMouseUp:] + 744
frame#17:0x00007fff87fd6788 AppKit`- [NSControl mouseDown:] + 669
frame#18:0x00007fff88524575 AppKit`- [NSWindow _handleMouseDownEvent:isDelayedEvent:] + 6322
frame#19:0x00007fff88525559 AppKit `- [NSWindow _reallySendEvent:isDelayedEvent:] + 212
frame# 20:0x00007fff87f6ad31 AppKit`- [NSWindow sendEvent:] + 517
frame#21:0x00007fff87eeaccb AppKit`- [NSApplication sendEvent:] + 2540
frame#22:0x0000000100225f35 Neat`- [NRMApplication sendEvent:] self = 0x00006000001205a0,_cmd = 0x00007fff88749e04,event = 0x0000608000725640)+ 1141 at NRMApplication.m:95
frame#23:0x00007fff87d51f3e AppKit`- [NSApplication run] + 796
frame#24:0x00007fff87d1b162 AppKit`NSApplicationMain + 1176
frame#25:0x0000000100012d67 Neat`main(argc = 3,argv = 0x00007fff5fbff718)+ 119 at main.m:21
frame#26:0x0000000100001e74 Neat`start + 52

这里是使用PDFDocument的removePageAtIndex方法的方法

   - (NSError *)removePageOpImpl:(NRMPDFOperation *)op 
{
NSLog(@\\\
Inside removePageOpImpl Method ...);
NSError * error = [self loadDocument];
if(!error)
{
NSUInteger index = [self pageIndexForId:[op pageId]];
NSLog(@页数:%ld,[self pageCount]);
if(index< [self pageCount])
{
NSLog(@PDF Document: - %@,[self pdfDocument]);
NSLog(@Index is:%ld,index);
@try {

[PDFDocument *] [self pdfDocument] removePageAtIndex:index]; //在这行应用程序获取冻结和控制结束。

NSLog(@删除后的页数:%ld,[self pageCount]);


}
@catch(NSException * exception){
NSLog(@Exception:%@,exception);
}
@finally {
NSLog(@Finally called);
[[self mutablePageIdList] removeObjectAtIndex:index];
[self updatePageLabelsFromIndex:index];
[self updateChangeCount:NSChangeDone];
self.contentsChanged = YES;
}
}
else
{
// TODO:error
}
}
return error;
}

任何人都可以建议我什么可能是问题...也附加屏幕截图的阻塞UI的队列



我尝试将dispatch_async应用到主队列中去执行PDFDocument页面删除操作,如下所示:

   - (NSError *)removePageOpImpl:(NRMPDFOperation *)op 
{
NSError * error = [self loadDocument];
if(!error)
{
NSUInteger index = [self pageIndexForId:[op pageId]];
if(index< [self pageCount])
{
dispatch_async(dispatch_get_main_queue(),^ {
[[self pdfDocument] removePageAtIndex:index];
[ [self mutablePageIdList] removeObjectAtIndex:index];
[self updatePageLabelsFromIndex:index];
[self updateChangeCount:NSChangeDone];
self.contentsChanged = YES;

} );
}
else
{
// TODO:error
}
}
return error;
}



现在应用程序没有挂起,但我陷入另一个问题。我有其他操作应该在removePageOpImpl操作后同步运行。但是它们在removePageOpImpl完成之前执行,这正在改变我的应用程序的行为。你可以建议我如何在removePageOpImpl之后同步执行其他操作。我读了关于完成处理程序,但在这种情况下我很困惑如何使用它。



请建议



你的主线程正在等待一个操作完成,但是这个操作由此跟踪指示)...





正在运行的后台线程,并且,如你所见,它正在等待一个信号量,最有可能只会从主线程发出信号。这有一些像 dispatch_sync 到主线程的指令。因为它发生在 PDFDocument 实现中,我想是它试图确保它在主线程上运行,然后返回给用户(读写器锁



因此,你的主线程正在等待一个操作完成,该操作正在等待主线程完成它想要做的事情。经典死锁。



这是因为主线程启动了保存,然后在进行之前等待一切完成(但是其他一些工作也需要在主线程上运行)。



您需要将该保存作为异步操作启动,因此在等待操作完成时它不会在主线程上运行,然后,保存完成后,如果必须更新UI,它可以通过完成块或在主线程上运行的委托报告其成功/失败。


I am using the PDFKit Framework into my cocoa app for PDFViewer.When I am trying to delete one of the page from the PDFDocument The app freezes at the line of code

[[self pdfDocument]  removePageAtIndex:0]; // can see this Problem only in Mac OS X 10.11

This works perfectly when I run the app in Mac OS X 10.10

I read all the related apple documents but I didn't get any solution yet.

Here is the backtrace :

* thread #1: tid = 0x85e1, 0x00007fff92571f5e libsystem_kernel.dylib`__psynch_cvwait + 10, queue = 'com.apple.main-thread', stop reason = signal SIGTERM
    frame #0: 0x00007fff92571f5e libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00000001006c05f7 libsystem_pthread.dylib`_pthread_cond_wait + 767
    frame #2: 0x00007fff904c6e32 Foundation`-[__NSOperationInternal _waitUntilFinished:] + 131
    frame #3: 0x00007fff904921fa Foundation`-[NSOperationQueue waitUntilAllOperationsAreFinished] + 254
  * frame #4: 0x000000010017efe1 Neat`-[NRMPDFCoordinator waitUntilAllOperationsAreFinished](self=0x0000608000ad3be0, _cmd=0x00007fff8877e285) + 145 at NRMPDFCoordinator.m:1362
    frame #5: 0x00000001000109cf Neat`-[NRMItemEditorDocument saveDocumentWithDelegate:didSaveSelector:contextInfo:](self=0x000060000094a190, _cmd=0x00007fff88777581, delegate=0x0000000000000000, didSaveSelector=0x0000000000000000, contextInfo=0x0000000000000000) + 1151 at NRMItemEditorDocument.m:325
    frame #6: 0x000000010001018a Neat`-[NRMItemEditorDocument saveDocument:](self=0x000060000094a190, _cmd=0x00007fff8874cbb4, sender=0x00006080003a8b20) + 58 at NRMItemEditorDocument.m:234
    frame #7: 0x0000000100013bef Neat`-[NRMItemEditorWindowController saveAndClose:](self=0x00006080003a8b20, _cmd=0x00000001002cf2d2, sender=0x000060000094a5b0) + 95 at NRMItemEditorWindowController.m:244
    frame #8: 0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
    frame #9: 0x00007fff87fc79b5 AppKit`-[NSApplication sendAction:to:from:] + 460
    frame #10: 0x00007fff87fd9bb2 AppKit`-[NSControl sendAction:to:] + 86
    frame #11: 0x00007fff87fd9adc AppKit`__26-[NSCell _sendActionFrom:]_block_invoke + 131
    frame #12: 0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
    frame #13: 0x00007fff87fd9a39 AppKit`-[NSCell _sendActionFrom:] + 144
    frame #14: 0x00007fff87068082 libsystem_trace.dylib`_os_activity_initiate + 75
    frame #15: 0x00007fff87fd805e AppKit`-[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2693
    frame #16: 0x00007fff88020d1c AppKit`-[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 744
    frame #17: 0x00007fff87fd6788 AppKit`-[NSControl mouseDown:] + 669
    frame #18: 0x00007fff88524575 AppKit`-[NSWindow _handleMouseDownEvent:isDelayedEvent:] + 6322
    frame #19: 0x00007fff88525559 AppKit`-[NSWindow _reallySendEvent:isDelayedEvent:] + 212
    frame #20: 0x00007fff87f6ad31 AppKit`-[NSWindow sendEvent:] + 517
    frame #21: 0x00007fff87eeaccb AppKit`-[NSApplication sendEvent:] + 2540
    frame #22: 0x0000000100225f35 Neat`-[NRMApplication sendEvent:](self=0x00006000001205a0, _cmd=0x00007fff88749e04, event=0x0000608000725640) + 1141 at NRMApplication.m:95
    frame #23: 0x00007fff87d51f3e AppKit`-[NSApplication run] + 796
    frame #24: 0x00007fff87d1b162 AppKit`NSApplicationMain + 1176
    frame #25: 0x0000000100012d67 Neat`main(argc=3, argv=0x00007fff5fbff718) + 119 at main.m:21
    frame #26: 0x0000000100001e74 Neat`start + 52

here is the method where I am using removePageAtIndex method of PDFDocument

-(NSError *)removePageOpImpl:(NRMPDFOperation *)op
{
    NSLog(@"\n Inside removePageOpImpl Method ...");
    NSError* error = [self loadDocument];
    if( !error )
    {
        NSUInteger index = [self pageIndexForId:[op pageId]];
        NSLog(@"Page count: %ld", [self pageCount]);
        if( index < [self pageCount] )
        {
            NSLog(@"PDF Document:-- %@", [self pdfDocument]);
            NSLog(@"Index is: %ld", index);
            @try {

                [(PDFDocument *)[self pdfDocument]  removePageAtIndex:index];//At this line the app getting freezed and control is ended.

                NSLog(@"Page count after delete: %ld", [self pageCount]);


            }
            @catch (NSException *exception) {
                NSLog(@"Exception: %@", exception);
            }
            @finally {
                NSLog(@"Finally called");
                [[self mutablePageIdList] removeObjectAtIndex:index];
                [self updatePageLabelsFromIndex:index];
                [self updateChangeCount:NSChangeDone];
                self.contentsChanged = YES;
            }
        }
        else
        {
            // TODO: error
        }
    }
    return error;
}

Can anyone please suggest me what might be the problem... also attached screenshots of the Queues which were blocking the UI

I tried applying dispatch_async on main queue to the PDFDocument page removal operations like below

- (NSError *)removePageOpImpl:(NRMPDFOperation *)op
{
    NSError* error = [self loadDocument];
    if( !error )
    {
        NSUInteger index = [self pageIndexForId:[op pageId]];
        if( index < [self pageCount] )
        {
                dispatch_async(dispatch_get_main_queue(), ^{
                        [[self pdfDocument] removePageAtIndex:index];
                        [[self mutablePageIdList] removeObjectAtIndex:index];
                        [self updatePageLabelsFromIndex:index];
                        [self updateChangeCount:NSChangeDone];
                        self.contentsChanged = YES;

                        });
        }
        else
        {
            // TODO: error
        }
    }
    return error;
}

Now the app is not hanging, but I fall into another problem. I have other operations which should run synchronously after the removePageOpImpl operations. but they are executing before removePageOpImpl completion which is changing the behaviour of my app. Can you suggest me how can I execute other operations synchronously after removePageOpImpl. I read about completion handler but, in this scenario I am confused of how to use it.

Please suggest

解决方案

You have created a nice little deadlock here.

Your main thread is waiting for an operation to finish, but that operation (indicated by this trace)...

is running on a background thread and, as you can see, it's waiting on a semaphore that is most likely only going to be signaled from the main thread. This has the earmarks of something like dispatch_sync to the main thread. Since it happens inside the PDFDocument implementation, I imagine it is trying to make sure it runs something on the main thread before returning to the user (reader/writer lock

Thus, your main thread is waiting for an operation to finish, and that operation is waiting for the main thread to finish what it's trying to do. Classic deadlock.

This happens because the main thread kicks off the save, and then waits for everything to complete before progressing (but some of that other work also needs to run on the main thread).

You need to kick off the save as an asynchronous operation, so it is not running on the main thread while waiting for the operations to complete. Then, when the save is done, if you have to update UI, it can report its success/failure via a completion block or delegate running on the main thread.

这篇关于PDFDocument removePageAtIndex:在更新到Mac OS X 10.11时不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆