• 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
Doesn't -willChangeValueForKey: copy the value before I change it?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Doesn't -willChangeValueForKey: copy the value before I change it?


  • Subject: Doesn't -willChangeValueForKey: copy the value before I change it?
  • From: Jerry Krinock <email@hidden>
  • Date: Fri, 14 Dec 2007 17:58:30 -0800

I've implemented a KVO-compliant NSMutableSet instance variable. It has this little mutator:

- (void)deleteSomeStuff {
    [self willChangeValueForKey:@"stuffs"] ;
#ifdef DO_IT_MY_WAY
    [_stuffs removeObject:[_stuffs anyObject]] ;
#else
    NSMutableSet* newStuffs = [_stuffs mutableCopy] ;
    [_stuffs release] ;
    [newStuffs removeObject:[newStuffs anyObject]] ;
    _stuffs = newStuffs ;
#endif
    [self didChangeValueForKey:@"stuffs"];
}

Either way, the observer gets notified, but if I DO_IT_MY_WAY, the "old" value in the notification is wrong; it is the same as the "new" value. My mental picture is that -willChangeValueForKey: is invoked to copy the "old" value immediately before a change. But it looks like maybe I'm wrong.

Can someone please explain, at a little higher level, what's wrong with my picture?

Jerry

******** DEMO PROJECT CODE ********

//#define DO_IT_MY_WAY

#import <Foundation/Foundation.h>

#pragma mark Observee Class

@interface Observee : NSObject {
    NSMutableSet* _stuffs ;
}

@end

@implementation Observee

+ (BOOL)automaticallyNotifiesObserversForKey: (NSString *)theKey {
    BOOL automatic;

if ([theKey isEqualToString:@"stuffs"])
automatic = NO;
else
automatic = [super automaticallyNotifiesObserversForKey:theKey];


    return automatic;
}

- (NSMutableSet *)stuffs {
    return _stuffs;
}

- (void)setStuffs:(NSMutableSet *)newStuffs {
    [newStuffs retain];
    [_stuffs release];
    [self willChangeValueForKey:@"stuffs"];
    _stuffs = newStuffs;
    [self didChangeValueForKey:@"stuffs"];
}

- (void)deleteSomeStuff {
    [self willChangeValueForKey:@"stuffs"] ;
#ifdef DO_IT_MY_WAY
    [_stuffs removeObject:[_stuffs anyObject]] ;
#else
    NSMutableSet* newStuffs = [_stuffs mutableCopy] ;
    [_stuffs release] ;
    [newStuffs removeObject:[newStuffs anyObject]] ;
    _stuffs = newStuffs ;
#endif
    [self didChangeValueForKey:@"stuffs"];
}

@end

#pragma mark Observer Class
@interface Observer : NSObject {
}

@end

@implementation Observer

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                         context:(void *)context {
    NSLog(@"Observer observed change:\n%@", change) ;
}

@end

#pragma mark Main

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Observer* observer = [[Observer alloc] init] ;
    Observee* observee = [[Observee alloc] init] ;

[observee addObserver:observer
forKeyPath:@"stuffs"
options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew)
context:NULL] ;


[observee setStuffs:[NSMutableSet setWithObjects:@"stuff1", @"stuff2", @"stuff3", nil]] ;

    [observee deleteSomeStuff] ;

    [pool release] ;
    return 0;
}


********** CONSOLE OUTPUT IF DO_IT_MY_WAY ************

2007-12-14 17:33:17.606 KVODemo[20028:10b] Observer observed change:
{
    kind = 1;
    new =     {(
        stuff1,
        stuff3,
        stuff2
    )};
    old = <null>;
}
2007-12-14 17:33:17.609 KVODemo[20028:10b] Observer observed change:
{
    kind = 1;
    new =     {(
        stuff3,
        stuff2
    )};
    old =     {(
        stuff3,
        stuff2
    )};
}


********** CONSOLE OUTPUT IF NOT DO_IT_MY_WAY ************

2007-12-14 17:44:07.246 KVODemo[20093:10b] Observer observed change:
{
    kind = 1;
    new =     {(
        stuff1,
        stuff3,
        stuff2
    )};
    old = <null>;
}
2007-12-14 17:44:07.249 KVODemo[20093:10b] Observer observed change:
{
    kind = 1;
    new =     {(
        stuff3,
        stuff2
    )};
    old =     {(
        stuff1,
        stuff3,
        stuff2
    )};
}



_______________________________________________

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


  • Follow-Ups:
    • Re: Doesn't -willChangeValueForKey: copy the value before I change it?
      • From: Chris Hanson <email@hidden>
    • Re: Doesn't -willChangeValueForKey: copy the value before I change it?
      • From: David Spooner <email@hidden>
  • Prev by Date: Drawing pixelated CIImage
  • Next by Date: Re: Is NSTableView sortDescriptors KVO compliant?
  • Previous by thread: Drawing pixelated CIImage
  • Next by thread: Re: Doesn't -willChangeValueForKey: copy the value before I change it?
  • Index(es):
    • Date
    • Thread