• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: KVO using threads
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: KVO using threads


  • Subject: Re: KVO using threads
  • From: "Paulo F. Andrade" <email@hidden>
  • Date: Wed, 9 May 2007 19:54:18 +0100

Ok I have tested this now and can confirm that it works as expected.
I had to make a slight change to the code earlier, here is the working version for future reference :)


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
NSArray *args = [NSArray arrayWithObjects: keyPath, object, change, context, nil];
//call the helper method
[self performSelectorOnMainThread:@selector(auxiliaryMethod:) withObject:args waitUntilDone:NO modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];

}


- (void)auxiliaryMethod:(NSArray *)args
{
NSString *keyPath;
id object;
NSDictionary *change;
void *context;

@try {
keyPath = [args objectAtIndex:0];
object = [args objectAtIndex:1];
change = [args objectAtIndex:2];
context = [args objectAtIndex:3];
}
@catch (NSException * e) {
// usually occurs because when constructing the NSArray args, context is nil
// meaning that the array only has 3 positions instead of 4
}
@finally {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}


Paulo F. Andrade 52439@IST
mailto: email@hidden


On 2007/05/01, at 22:11, Chris Kane wrote:

Actually KVO and its messages are thread-safe. But the objects that send (by having their properties changed, say) and receive (observers) the KVO notifications may not be thread-safe, or expect to receive the messages on different threads, which may require special additional actions to handle. Such is the case with the Bindings-related objects (like the controllers) in AppKit.

One general solution might be to interpose a proxy-like object between the model objects (presumably thread-safe) and the controllers. I called this a receptionist pattern in my WWDC 2006 talk. The receptionist object should implement observeValueForKeyPath:..., you should initialize the receptionist with the real object (say, a controller), and you should use the receptionist wherever you would otherwise refer to the controller. (This last step is sometimes difficult to do in all cases.) When the receptionist receives a KVO observeValue... call, it should save the parameters in a little private helper object, and send itself a private message to be performed on the main thread (performSelectorOnMainThread...) to deliver that message with its parameters to the real object (which will be on the main thread then). No, I don't have an example which does this.

That handles (if you can pull it off) the model -> controller -> view data flow direction. Presumably if your model objects are thread-safe, changes on the main thread coming down from the view to the model objects will be fine.

On the sending (KVO-notification-causing) side of things, using automatic KVO is not entirely thread-safe because the willChange/ change/didChange combination is not atomic. Using manual KVO (sending the willChange... and didChange... methods yourself in all the right places) you can make these atomic with your own lock (I suggest using the object itself as the lock with @synchronized() is a reasonable default choice of locking technique). Using automatic KVO can, for example, make the change dictionary that observers get completely wrong with respect to the change that occurred due to execution ordering issues.


Chris Kane Cocoa Frameworks, Apple


On May 1, 2007, at 12:24 PM, Scott Anguish wrote:

No. KVO messages are not threadsafe.

On May 1, 2007, at 2:40 PM, Paulo F. Andrade wrote:

Hi!

Does KVO work when the changes are made in different thread?

I'm changing a tooMany relationship using the add<Key>Object: method generated by the Xcode modeling tool.
The changes however aren't reflected in my tableview. I've also tried using the mutableSetForKey:.


I know my tableView is set up correctly because if I restart my application (causing all changes do flush to the SQLite store), every change I made shows up correctly!

I've search the net for this and found that Bindings don't work with DO, does this means they don't work with threads?

Paulo F. Andrade 52439@IST
mailto: email@hidden


_______________________________________________

Cocoa-dev mailing list (email@hidden)

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


_______________________________________________

Cocoa-dev mailing list (email@hidden)

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


References: 
 >KVO using threads (From: "Paulo F. Andrade" <email@hidden>)
 >Re: KVO using threads (From: Scott Anguish <email@hidden>)
 >Re: KVO using threads (From: Chris Kane <email@hidden>)

  • Prev by Date: Re: iSight Capture
  • Next by Date: Re: World Builder Type Application
  • Previous by thread: Re: KVO using threads
  • Next by thread: problem blitting to fullscreen window
  • Index(es):
    • Date
    • Thread