configurePersistentStoreCoordinator not called for saveAs NSPersistentDocument

后端 未结 4 1492
醉梦人生
醉梦人生 2021-01-21 11:18

I experience an odd behaviour regarding saving an NSPersistentDocument. I can create a new document which is autosaved without an issue. But when I save it write(to: ofTyp

4条回答
  •  情话喂你
    2021-01-21 11:48

    Thank you @Wizard of Kneup!

    That clearly shows the application certainly read a document file and then encounter the error.

    Let's start investigation.

    (1) What file does the app attempt to read?

    (lldb) breakpoint set -n '-[NSBinaryObjectStoreFile readFromFile:error:]'    
    Breakpoint 3: # locations.
    

    Run the app again to reproduce the problem. Once the breakpoint hits, type the following commands to the lldb prompt:

    po $rdi
    p (SEL)$rsi
    po $rdx
    po $rcx
    po $r8 
    po $r9
    

    The filename would be shown. Disable the breakpoint. Use the number # which was returned at breakpoint set before. e.g. 3

    (lldb) breakpoint disable 3
    

    (2) What object does the app try to decode?

    (lldb) breakpoint set -n '-[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]'
    Breakpoint 4: # locations.
    

    Same as above. Use a set of po commands to get some information. It seems an array of something.

    (lldb) breakpoint disable 4
    

    (3) What class does the app reject to decode?

    (lldb) breakpoint set -n '-[NSCoder _validateAllowedClass:forKey:allowingInvocations:]'
    

    I wrote the breakpoints one by one and disable each time. But, no need to do that. Alternatively, set all breakpoints at a time and do hit-and-investigate-then-continue.

    The questions are why the app reads the file. That might be for migration.

    -[NSPersistentStoreCoordinator migratePersistentStore:toURL:options:withType:error:]
    

    But why override func configurePersistentStoreCoordinator() is not called? I have no knowledge on that now.

    I hope you would have some hints for getting closer to a solution.

    Added:

    To set a breakpoint, sometime we need to stop at the very beginning of execution of application.

    For instance, set a breakpoint at init() of AppDelegate to get a chance of manually setting breakpoints.

    class AppDelegate: NSObject, NSApplicationDelegate {
    
      override init() {
    =>  super.init()
      }
    
    }
    

    Appended:

    I had misunderstood. The correction:

    The func configurePersistentStoreCoordinator seems to be called when a class NSPersistentStore is instantiated with a desired URL, i.e. filename. So the timing is not related to the action of reading from nor writing to a document file. Instead, it is the first time when the internal document is about to be connected to the URL.

    • Opening an existing file -> the func configurePersistentStoreCoordinator is called.
    • File > New and then Save... -> the func is called.

    The fact we had seen that func configurePersistentStoreCoordinator was not called upon SaveAs seems to be normal, if the document has been loaded from an existing file in advance. The options for the NSPersistentStore we provided in that func are already there, I think.

    Tips for setting a breakpoint

提交回复
热议问题