NSUserDefaults, threads, and binding
NSUserDefaults, threads, and binding
- Subject: NSUserDefaults, threads, and binding
- From: Greg Hoover <email@hidden>
- Date: Wed, 16 Apr 2008 13:10:33 -0700
I've encountered a situation where NSUserDefaults is definitely not
thread safe. Consider an user defaults value bound to an interface
object. A background thread modifies this value, first acquiring the
lock to write to the user defaults, writes the new value, and finally
triggers a KVO notification, in turn triggering a call to the main
thread to draw the updated value in the interface. Meanwhile the main
thread wants to access a value in the user defaults too, but blocks on
the lock because the background thread acquired it. The application
is now deadlocked with both threads waiting on the other.
This is my understanding of what's happening in my app based on the
following stack traces. An existing post mentions putting all access
to NSUserDefaults in a @synchronized block. Before doing this, can
anyone verify that that works?
Main Thread:
61 -[NSWindow makeKeyAndOrderFront:] + 189 (in AppKit)
[0x95308afa]
61 -[NSWindow
orderWindow:relativeTo:] + 105 (in AppKit) [0x953410d8]
61 -[NSWindow
_reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] +
1354 (in AppKit) [0x95341681]
61 -
[NSWindow displayIfNeeded] + 189 (in AppKit) [0x95285ab9]
61 -
[NSView displayIfNeeded] + 933 (in AppKit) [0x95285f09]
61 -
[NSView
_displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] +
3090 (in AppKit) [0x9534552d]
61 -
[NSThemeFrame
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView
:] + 306 (in AppKit) [0x953489f7]
61 -
[NSView
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView
:] + 759 (in AppKit) [0x953490b4]
61 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1902
(in AppKit) [0x9534aaa5]
...
61
-[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1050 (in
AppKit) [0x9534a751]
61
-[NSTextView _drawRect:clip:] + 2579 (in AppKit) [0x953b07a6]
61
-[NSTextView drawRect:] + 250 (in AppKit) [0x953b09fd]
61
-[NSUserDefaults(NSUserDefaults) objectForKey:] + 36 (in Foundation)
[0x91907524]
61
_semaphore_wait_signal_trap + 10 (in libSystem.B.dylib) [0x91403a2e]
Background Thread:
61 -[NSUserDefaults(NSUserDefaults)
setObject:forKey:] + 113 (in Foundation) [0x91964821]
61 __CFXPreferencesSetValue + 102 (in
CoreFoundation) [0x90966c46]
61 -
[CFXPreferencesPropertyListSource setValue:forKey:] + 86 (in
CoreFoundation) [0x90965f86]
61 -
[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 546
(in Foundation) [0x91907f22]
61 _NSKVONotify + 62 (in
Foundation) [0x9198b58e]
61 -[NSController
observeValueForKeyPath:ofObject:change:context:] + 949 (in AppKit)
[0x95488920]
61 -[NSController
_notifyObserversForKeyPath:change:] + 248 (in AppKit) [0x9526b15e]
61 -
[NSObject(NSKeyValueObservingPrivate)
_notifyObserversForKeyPath:change:] + 373 (in Foundation) [0x9191be45]
61 _NSKVONotify + 62
(in Foundation) [0x9198b58e]
61 -[NSEditableBinder
_observeValueForKeyPath:ofObject:context:] + 124 (in AppKit)
[0x9544ab24]
61 -[NSView
_setHidden:] + 50 (in AppKit) [0x9527290d]
61 -
[NSView(NSInternal) _setHidden:setNeedsDisplay:] + 1318 (in AppKit)
[0x95272e3c]
61 -[NSView
_invalidateGStatesForTree] + 49 (in AppKit) [0x9526648a]
61 -[NSView
renewGState] + 50 (in AppKit) [0x95266690]
61 -
[NSViewHierarchyLock lockForWritingWithExceptionHandler:] + 50 (in
AppKit) [0x9589afed]
61 -
[NSViewHierarchyLock _lockForWriting:handler:] + 416 (in AppKit)
[0x9589b43d]
61
___semwait_signal + 10 (in libSystem.B.dylib) [0x9140abce]
_______________________________________________
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