• 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: Enumerating over managed object to-many relationships
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

re: Enumerating over managed object to-many relationships


  • Subject: re: Enumerating over managed object to-many relationships
  • From: Ben Trumbull <email@hidden>
  • Date: Sat, 3 Nov 2007 17:18:38 -0700

After compiling my app on Leopard I now run into a number of
"Collection was mutated while being enumerated" exceptions.
The problem is that it's not obvious why/how I am editing the
collection and neither how to solve it the best way.

Take this example:

	// given a paper, get all its authors, iterate over them and delete
the ones with just one paper
	NSSet *authors = [paper valueForKey: @"authors"];
	NSEnumerator *e = [authors objectEnumerator];
	Author *author;
	while(author = [e nextObject]){
		if([[author valueForKey: @"papers"]count] == 1){
			[author removePapersObject: paper];
			[context deleteObject: author];
		}
	}

Do I indeed change the authors set ? Indirectly and ultimately yes,
if I would ask for  [paper valueForKey: @"authors"] again I would get
a different set, but does it refresh this everytime this set then?

You are changing the collection you are iterating over during the loop.

Can someone clearly explains how the situation works, why the above
is bad, and what the best way of doing this is (perhaps also showing
the ObjC 2.0 way)?

Here's how I would write that on 10.5

// given a paper, get all its authors, iterate over them and delete the ones with just one paper
NSSet *authors = [[paper authors] copy];
for(Author* a in authors) {
if ([[a papers] count] == 1) {
[a removePapersObject: paper];
[context deleteObject: a];
}
}
[authors release];



Although, depending on how you set up the delete rules in your model, you could let the framework do more of the work. For example, authors might have a nullify delete rule to the papers, in which case you don't need to call -removePapersObject yourself. Instead you can let if happen at the end of the event when the changes are coalesced and the deletions cascaded. In that case, you wouldn't need to make a copy, since the side effects on the authors set happens outside the loop.


- Ben


_______________________________________________

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


  • Prev by Date: Re: Initializing the menubar
  • Next by Date: SenTesttingKit.framework runtime failure
  • Previous by thread: Re: Enumerating over managed object to-many relationships
  • Next by thread: Best practice for hidden keyboard shortcuts
  • Index(es):
    • Date
    • Thread