• 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: bindings from threads
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bindings from threads


  • Subject: Re: bindings from threads
  • From: Chris Hanson <email@hidden>
  • Date: Thu, 5 Oct 2006 21:07:26 -0700

On Oct 5, 2006, at 11:33 AM, Ryan Britton wrote:

The approach to take has two parts. Since bindings are typically used to update UI widgets, the update notifications need to be called on the main thread. A typical update may look something like this:

[self performSelectorOnMainThread:@selector(willUpdateValueForKey:) withObject:@"someKey" waitUntilDone:YES];
//Update the value for someKey
[self performSelectorOnMainThread:@selector(didUpdateValueForKey:) withObject:@"someKey" waitUntilDone:YES];


That handles the first part. For the second part you need to make sure your accessors are threadsafe. You can either accomplish this with locks or any of the other various thread safety directives or ensure that values are only updated on the main thread.

The above is not what you should do. In particular, you should not be using main-thread performs to post KVO change notifications that are distinct from the actual change to your object.


To see why the above is broken, consider this scenario:

(1) Thread 2 asks the main thread to perform the following, which it does:

  [self willChangeValueForKey:@"someKey"];

Then there's a random context switch.

(2) Something on the main thread also changes that object, which invokes the following:

  [self willChangeValueForKey:@"someKey"];
  _someKey = @"foo";

Then there's a random context switch.

(3) Thread 2 happens to be chosen to run again, which does the following:

  _someKey = @"bar";

and then asks the main thread to perform the following:

  [self didChangeValueForKey:@"someKey"];

Then there's a random context switch.

(4) The main thread finally executes:

  [self didChangeValueForKey:@"someKey"];

Congratulations! The state of your object is all messed up now, and that corruption is propagating to the observers of the key "someKey" -- especially if they were interested in the old and/or new values of the key for some purpose.

Also, "thread-safe" accessors are almost *never* what you want; typically an object has enough state that thread safety needs to be treated as a way of delineating *transactions* on an object or even the entire graph of related objects. This is necessary to prevent the object graph from becoming inconsistent when there can be multiple clients performing operations on it.

As I've said before, if you're considering doing *anything* with threads, you should follow well-established patterns of use such as producer/consumer work queues. You cannot just dive in to creating multithreaded applications by throwing a thread in here and a thread in there to "make things faster." It not only doesn't work, it can be harmful to both the stability and performance of your application.

  -- Chris

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >bindings from threads (From: "Jim Thomason" <email@hidden>)
 >Re: bindings from threads (From: Ryan Britton <email@hidden>)

  • Prev by Date: Re: bindings from threads
  • Next by Date: Issue while calling run modal after showing a sheet
  • Previous by thread: Re: bindings from threads
  • Next by thread: Re: bindings from threads
  • Index(es):
    • Date
    • Thread