On Jul 12, 2014, at 5:57 PM, Ken Thomases <k...@codeweavers.com> wrote:
> You could do it this way: > __block void (^__unsafe_unretained > innerFindItemForIdentifierInArray)(NSArray *); Thanks. I had gotten as far as thinking that I needed a second block variable for the recursive call, but the proper placement of __unsafe_unretained didn't come to me. > This still has a problem. It doesn't stop when you intend it to. Any given > -enumerate... call will stop if it directly finds the match, but an outer > call won't. You could add "if (returnItem) *stop = YES;" after the recursive > call. Or, you could pass the "stop" variable into the recursive call so that > an inner call can set it. Thank you for catching that! I was so focused on getting the block syntax right that I completely overlooked the recursion issue. Here's the final method. I should mention that my datasource is a property list (hence my use of dictionaries). The root array does not have an identifier. That's why I start right out with -enumerateObjectsUsingBlock:. I chose to use blocks instead of recursive method calls partly to force myself to become more familiar with block syntax, and partly because I understand that blocks executing on the stack are likely to be faster. This method may have to enumerate the datasource many times, depending on how many of the outline rows are expanded. - (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object { // Datasource method per NSOutlineViewDataSource formal protocol. Required if using autosaveExpandedItems. Called when application launches, once for each item in the autosaved array in the user defaults preferences file. AppKit calls this before -awakeFromNib, so the source list data source must be populated in the designated initializer. NSString *identifier = [NSKeyedUnarchiver unarchiveObjectWithData:object]; __block id returnItem = nil; __block void (^__unsafe_unretained innerFindItemForIdentifierInArray)(NSArray *); __block void (^findItemForIdentifierInArray)(NSArray *) = ^(NSArray *contents) { [contents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([[obj objectForKey:ID_KEY] isEqualToString:identifier]) { returnItem = obj; *stop = YES; } id subarray = [obj objectForKey:CONTENTS_KEY]; if (subarray) { innerFindItemForIdentifierInArray(subarray); // recursive if (returnItem) { *stop = YES; } } }]; }; innerFindItemForIdentifierInArray = findItemForIdentifierInArray; findItemForIdentifierInArray([self sourceListContents]); return returnItem; } -- Bill Cheeseman - b...@cheeseman.name _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com