Hi all,

Thanks for your suggestions and help so far.

I believe my problem is that my model object is a subclass of CATiledLayer. Synthesized accessor methods for the CATiledLayer subclass are not key value observing compliant. Yet, by changing the immediate superclass of the model object to NSObject, the synthesized accessor methods are KVO compliant. Any ideas what I can do besides provide my own accessor methods?

Below I have some code for a Cocoa Application template in Xcode. I have an optional #define INHERITS_FROM_NSOBJECT. I have two custom classes, Controller (inheriting from NSObject) and CustomLayer (inheriting from CATiledLayer or NSObject). CustomLayer inherits from NSObject if INHERITS_FROM_NSOBJECT has been #define'd.

In the XIB I have a top level instance of Controller. It contains an outlet pointing to the content view of the XIB's window.

Thanks again!

Kiel

//#define INHERIT_FROM_NSOBJECT 1

#ifdef INHERIT_FROM_NSOBJECT
@interface CustomLayer : NSObject {
#else
@interface CustomLayer : CATiledLayer {
#endif
        CGFloat ivar1;
        CGFloat ivar2;
        NSString *stringIvar;
}

@property CGFloat ivar1;
@property CGFloat ivar2;
@property (retain, nonatomic) NSString *stringIvar;
@end

@implementation CustomLayer

- (id)init
{
        if (self = [super init]) {
                self.ivar1 = 1.0;
                self.ivar2 = 1.0;
#ifndef INHERIT_FROM_NSOBJECT
                self.bounds = CGRectMake(0.0, 0.0, 2000.0, 2000.0);
                self.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
#endif
                self.stringIvar = @"String ivar";
                
NSLog(@"Created layer %@ with ivar1 == %f, ivar2 == %f, stringIvar == %@", self, self.ivar1, self.ivar2, self.stringIvar);
        }
        
        return self;
}

- (void)dealloc
{
        self.stringIvar = nil;
        [super dealloc];
}

@synthesize ivar1;
@synthesize ivar2;
@synthesize stringIvar;
@end


@interface Controller : NSObject {
        IBOutlet NSView *view;
}

@end

#import "Controller.h"
#import "CustomLayer.h"

static NSUInteger IvarChange, StringIvarChange;

@implementation Controller

- (void)awakeFromNib
{
        [view setWantsLayer:YES];
        
        //create catiledlayer or nsobject subclass with observed properties
        CustomLayer *layer = [[[CustomLayer alloc] init] autorelease];
[layer addObserver:self forKeyPath:@"ivar1" options:0 context:&IvarChange]; [layer addObserver:self forKeyPath:@"ivar2" options:0 context:&IvarChange]; [layer addObserver:self forKeyPath:@"stringIvar" options:0 context:&StringIvarChange];
        
#ifdef INHERIT_FROM_NSOBJECT
        //leak memory deliberately for the sake of the example
        [layer retain];
#else
//add layer as a sublayer to force the CoreAnimation machinery to use the tiled layer subclass
        [[view layer] addSublayer:layer];
#endif
        
        //setup a timer to modify the properties of the layer object
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:layer, @"layer", nil]; [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(timerDidFire:) userInfo:userInfo repeats:YES];
}

- (void)timerDidFire:(NSTimer *)timer
{
        NSDictionary *userInfo = [timer userInfo];
        CustomLayer *layer = [userInfo valueForKey:@"layer"];
        
NSLog(@"Manipulating ivar1 (%f) and ivar2 (%f) of layer %@", layer.ivar1, layer.ivar2, layer);
        layer.ivar1 = layer.ivar1 + 1.0;
        layer.ivar2 = layer.ivar2 + 1.0;
NSLog(@"Manipulated ivar1 (%f) and ivar2 (%f) of layer %@", layer.ivar1, layer.ivar2, layer);
        
        NSLog(@"Manipulating string ivar (%@)", layer.stringIvar);
        layer.stringIvar = [[NSDate date] description];
        NSLog(@"Manipulated string ivar (%@)\n\n", layer.stringIvar);
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
        NSLog(@"%...@.%@ == %@", object, keyPath, [object valueForKey:keyPath]);
        
    if (context == &IvarChange) {
                NSLog(@"Float ivar change");
                
        } else if (context == &StringIvarChange) {
                NSLog(@"String ivar change");
                
        } else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
}

@end

On 20/05/2009, at 10:45 AM, Jerry Krinock wrote:


On 2009 May 19, at 16:52, Kiel Gillard wrote:

I feel I may be missing something very simple but I have no idea what.

Never tried it with structs like CGRect but I just bound some integers like this yesterday and they KVO works. The title of your message says "not KVO compliant". Please clarify: Is the console log telling you this, or is this your interpretation?

Any suggestions?

Post some code.

_______________________________________________

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/kiel.gillard%40gmail.com

This email sent to kiel.gill...@gmail.com

_______________________________________________

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