Compiler does not synthesize KVO compliant properties for CATiledLayer subclass (was: Synthesized properties for scalars not KVO compliant)
Compiler does not synthesize KVO compliant properties for CATiledLayer subclass (was: Synthesized properties for scalars not KVO compliant)
- Subject: Compiler does not synthesize KVO compliant properties for CATiledLayer subclass (was: Synthesized properties for scalars not KVO compliant)
- From: Kiel Gillard <email@hidden>
- Date: Fri, 22 May 2009 10:12:10 +1000
- Resent-date: Fri, 22 May 2009 13:40:16 +1000
- Resent-from: Kiel Gillard <email@hidden>
- Resent-message-id: <email@hidden>
- Resent-to: cocoa-dev cocoa-dev <email@hidden>
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 (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
_______________________________________________
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