[Adium-devl] Problems with AIPreferenceController and KVO

Evan Schoenberg evan.s at dreskin.net
Tue Jan 8 03:06:15 UTC 2008


In [22176] I introduced a memory efficiency change to  
AIPreferenceController. I wrote:
> The preference files are read heavily at startup but aren't, as a  
> whole, used regularly after that.  When an object's preferences are  
> used, we often use ma
> ny of its settings in rapid succession as each relevant piece of  
> information is read and used.
>
> There's no reason to keep all that data in memory permanently.   
> After 30 seconds of disuse for a given cache key (which for global  
> preferences means for a
> given group and for object-specific preferences means all  
> preferences for that object), we now remove it from our in-memory  
> cache.  It'll be re-read from d
> isk when needed later.

I definitely think this is a Good Change.

However, it breaks KVO for AIPreferenceController horribly.  When a  
dictionary for a group is removed from the cache, it hasn't changed,  
and asking the preference controller about it would retrieve the  
(same) information and return it.  However, removing it without  
calling the willChangeValueForKey: / didChangeValueForKey: leads to  
errors like:

2008-01-07 19:08:29.049 Adium[24676:10b] Exception raised during  
posting of notification.  Ignored.  exception: 'Cannot remove an  
observer <AILoggerPlugin 0x7d38140> for the key path "Logging.Enable  
Logging" from <AIPreferenceController 0x782ce0>, most likely because  
the value for the key "Logging" has changed without an appropriate KVO  
notification being sent. Check the KVO-compliance of the  
AIPreferenceController class.'  invoked observer method: '*** - 
[AIAdium applicationWillTerminate:]'  observer: 0x770400  notification  
name: 'NSApplicationWillTerminateNotification'

when the 30 seconds has passed and then the observer tries to de- 
register.

We're removing the dictionary "Logging" (in the case of the error  
above), and we would need to call willChange/didChange for every  
keypath being observed within the Logging group.  However, posting  
such notifications would simply make KVO call valueForKey: again,  
which would reload the information from disk.

One possibility would be to simply not de-cache groups (and objects)  
which are being observed via KVO... but that obviously sucks pretty  
badly since we could theoretically still be keeping everything in  
memory.

Any suggestions?

-Evan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://adium.im/pipermail/devel_adium.im/attachments/20080107/175afe84/attachment-0001.html>


More information about the devel mailing list