Poof! Recently-saved Core Data document suddenly gets dirty
Poof! Recently-saved Core Data document suddenly gets dirty
- Subject: Poof! Recently-saved Core Data document suddenly gets dirty
- From: Jerry Krinock <email@hidden>
- Date: Fri, 23 Jan 2009 22:44:02 -0800
In my Core Data Document-Based application, I have a menu item which
imports settings from a legacy application. For each setting found,
it programatically creates a new document, saves it, and leaves the
new document window open. When all done, the user gets a modal dialog
showing a list of what was imported.
This works fine, except when importing some setting datasets,
sometimes, after the modal dialog has been displayed, often 2 seconds
later -- poof -- the created document receives an updateChangeCount:
message, and in its window, the 'close' button becomes dirty. During
other program runs with the same data, this does not happen until
after I dismisses the modal dialog. Very weird. In either case, my
observer of NSManagedObjectContextObjectsDidChangeNotification does
^not^ receive any notification when the document gets dirtied. What
could dirty the document without triggering this notification?
To investigate, I saved the dirty document with a new name, thinking
that whatever changed would be different between the two xml files.
One of my entities has an attribute which is a transformable
("encodable") dictionary of a few short strings. The only significant
difference I see between the two files is that, for one of my objects,
the base64 representation of these dictionaries is different. Re-
reading both documents into my app with some extra logging however,
they both decode to exactly the same key/value pairs.
Examining the xml more closely with BBEdit, in one test I found the
two encoded dictionaries to be just slightly different, both
containing exactly 621 base64 characters, but there were two blocks of
four characters that occur in different locations, and, near the end,
four characters were different. In another test, the differences were
more substantial -- character counts were 525 vs 641, and maybe half
of the characters were different.
Apparently, encoding of these dictionaries is non-deterministic, so I
modified my "supersetters" (methods that set key/value pairs within
these dictionaries) to make sure that the actual dictionary setter is
only invoked if there is a genuine difference between the new and old
values. [1] But that did not help, and indeed an NSLog placed in an
"else" branch of this condition, indicating an attempt to re-set a key
to the same value, never runs.
I over-rode updateChangeCount: and put a breakpoint in there. The
call stack is shown below [2]. Are there any clues in there as to
what is triggering this extraneous updateChangeCount:?
During the import, some transient properties are set and gotten, but
this is all complete before the document is saved.
I realize I could probably paper over this problem by disabling undo
registration during the import, or by sending -
updateChangeCount:NSChangeCleared when I dismiss my dialog. But I'm
worried about not knowing the cause of the weird behavior before I
ship this thing.
Thanks for reading,
Jerry Krinock
[1] At any rate, this might cause extraneous undo registrations.
I've noticed more than once when using others' Core Data apps that I
sometimes need to click "Undo" seven or eight times times before
anything happens :|
[2] Call Stack for the extraneous updateChangeCount:. In #0,
Bookshelf is my NSPersistentDocument subclass. All the other
functions are Apple's except for #53, #54 and #55.
#0 0x0003dfdc in -[Bookshelf updateChangeCount:] at Bookshelf.m:1344
#1 0x91fd8e1a in _nsnote_callback
#2 0x9702f8da in __CFXNotificationPost
#3 0x9702fbb3 in _CFXNotificationPostNotification
#4 0x91fd6080 in -[NSNotificationCenter
postNotificationName:object:userInfo:]
#5 0x91fdf8c8 in -[NSNotificationCenter postNotificationName:object:]
#6 0x9203fc58 in -[NSUndoManager endUndoGrouping]
#7 0x970d6a4c in -[NSSet makeObjectsPerformSelector:withObject:]
#8 0x9201e390 in +[NSUndoManager(NSUndoManagerPrivate)
_endTopLevelGroupings]
#9 0x90eecefb in NSMenuItemCarbonEventHandler
#10 0x933121e3 in HIObject::Construct
#11 0x93311ad6 in HIObject::Create
#12 0x93311a06 in HIObjectCreate
#13 0x933500f4 in _HIMenuGetItemView
#14 0x9334fecf in HIMenuGetItemView
#15 0x93551864 in MenuData::ShouldReturnItemViewAsChild
#16 0x93552247 in MenuData::HandleGetAccessibleChildren
#17 0x93553a1c in MenuData::ContentViewGetNamedAccessibleAttribute
#18 0x9339a172 in HIObject::DispatchAccessibilityEvent
#19 0x93551913 in MenuData::MenuContentViewAccessibilityHandler
#20 0x93317143 in DispatchEventToHandlers
#21 0x9331657d in SendEventToEventTargetInternal
#22 0x933163e2 in SendEventToEventTargetWithOptions
#23 0x934ad808 in Accessible::SendEvent
#24 0x934aea5e in Accessible::GetNamedAttributeData
#25 0x934aecaa in HLTBCopyUIElementAttributeValue
#26 0x935522c8 in MenuData::GetAccessibleChildrenSelf
#27 0x9339ab4f in HIObject::GetNamedAccessibleAttributeSelf
#28 0x93553aca in MenuData::GetNamedAccessibleAttributeSelf
#29 0x9339a172 in HIObject::DispatchAccessibilityEvent
#30 0x93399e44 in HIObject::HandleClassAccessibilityEvent
#31 0x9331763c in HIObject::EventHook
#32 0x93317143 in DispatchEventToHandlers
#33 0x9331657d in SendEventToEventTargetInternal
#34 0x933163e2 in SendEventToEventTargetWithOptions
#35 0x934ad808 in Accessible::SendEvent
#36 0x934aea5e in Accessible::GetNamedAttributeData
#37 0x934aeaf8 in Accessible::GetNamedAttributeData
#38 0x934af423 in CarbonCopyAttributeValuesCallback
#39 0x90fb9ff4 in CopyAttributeValues
#40 0x9231a2f8 in _AXXMIGCopyAttributeValues
#41 0x9232124a in _XCopyAttributeValues
#42 0x922ea4d8 in mshMIGPerform
#43 0x9704e8e8 in CFRunLoopRunSpecific
#44 0x9704ecd8 in CFRunLoopRunInMode
#45 0x9333f2c0 in RunCurrentEventLoopInMode
#46 0x9333f0d9 in ReceiveNextEventCommon
#47 0x9333ef4d in BlockUntilNextEventMatchingListInMode
#48 0x90c2cd7d in _DPSNextEvent
#49 0x90c2c630 in -[NSApplication
nextEventMatchingMask:untilDate:inMode:dequeue:]
#50 0x90e699ef in -[NSApplication _realDoModalLoop:peek:]
#51 0x90e6412d in -[NSApplication runModalForWindow:]
#52 0x00158a36 in -[SSYAlert runModalDialog] at SSYAlert.m:1088
#53 0x0008d177 in +[LegacyImporter importLegacyPrefsToThisApp] at
LegacyImporter.m:953
#54 0x0008d558 in +[LegacyImporter importLegacyPrefsIfFound] at
LegacyImporter.m:996
#55 0x0002d00f in -[BkmxAppDel importLegacy:] at BkmxAppDel.m:980
#56 0x90cfe53b in -[NSApplication sendAction:to:from:]
#57 0x90dad17c in -[NSMenu performActionForItemAtIndex:]
#58 0x90dace81 in -[NSCarbonMenuImpl
performActionWithHighlightingForItemAtIndex:]
#59 0x90d89b5a in AppKitMenuEventHandler
#60 0x93317143 in DispatchEventToHandlers
#61 0x9331657d in SendEventToEventTargetInternal
#62 0x93332ed2 in SendEventToEventTarget
#63 0x9336723d in SendHICommandEvent
#64 0x9338da8f in SendMenuCommandWithContextAndModifiers
#65 0x9338da4c in SendMenuItemSelectedEvent
#66 0x9338d95e in FinishMenuSelection
#67 0x9336a4ec in MenuSelectCore
#68 0x93369ed7 in _HandleMenuSelection2
#69 0x93369d4b in _HandleMenuSelection
#70 0x90cc650b in _NSHandleCarbonMenuEvent
#71 0x90c2d26a in _DPSNextEvent
#72 0x90c2c630 in -[NSApplication
nextEventMatchingMask:untilDate:inMode:dequeue:]
#73 0x90c2566b in -[NSApplication run]
#74 0x90bf28a4 in NSApplicationMain
#75 0x000a92c7 in main at Main.m:22
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden