On Dec 2, 2009, at 12:18, Kyle Sluder wrote:

> On Wed, Dec 2, 2009 at 11:37 AM, Quincey Morris
> <quinceymor...@earthlink.net> wrote:
>> In some cases, you can do the wrong thing -- change the instance variable 
>> directly -- and still be KVO compatible if you manually call the 
>> willChangeValueForKey:/didChangeValueForKey: methods (or the similar ones 
>> designed specifically for collections), but that approach is kind of frowned 
>> on, not to mention difficult to get right in general.
> 
> I don't know why you call this the "wrong thing."  This is very much a
> reasonable thing to do, and in many non-trivial cases you will have to
> do exactly this.

Infelicitous wording on my part. I was trying to say that the "wrong" thing 
(changing the instance variable directly, and not causing any notifications) 
can be converted into a "right" thing by triggering the notifications manually. 
Once you add willChange/didChange, it isn't wrong any more. I still think that 
this approach has started to smell a little bit *in general*, now that we have 
keyPathsForValuesAffecting<Key>, but if it's necessary to generate the 
notifications manually, then I wouldn't call that wrong.

I also need to retract, partially, another thing I said. There is, technically, 
a way of getting a immutable array proxy directly: 'valueForKey:', but it has 
its pitfalls. For example, consider this implementation:

@interface Year
@property (readonly) NSArray* seasons;
@end

@implementation Year

- (NSUInteger) countOfSeasons {
        return 4;
}

- (id) objectInSeasonsAtIndex: (NSUInteger) index {
        switch (index) {
                case 0: return @"Spring";
                case 1: return @"Summer";
                case 2: return @"Autumn";
                default: return @"Winter";
        }
}

- (NSArray*) seasons {
        // return the immutable array proxy here
}

Since the only way of getting the immutable array proxy is 'valueForKey:', it 
would seem like the correct implementation of that last method would be:

- (NSArray*) seasons {
        return [self valueForKey: @"seasons"];
}

However, that will in fact produce an infinite recursive loop, since 
'valueForKey:' calls the getter method if it exists. There's no way of having 
BOTH the getter AND access to the immutable array proxy via the getter. What's 
really needed is:

- (NSArray*) seasons {
        return [self immutableArrayValueForKey: @"seasons"];
}

but of course that doesn't exist in the API.


_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to