键/值观察不触发属性定义为:@property(readwrite,retain)__ attribute __((NSObject))CGImageRef thumbnailImage

时间:2011-09-09 15:15:21

标签: objective-c key-value-observing

我有一个具有如下属性定义的类:

// Interface
@property (retain) __attribute__((NSObject)) CGImageRef thumbnailImage;

// Implementation
@synthesize thumbnailImage;

问题是self.thumbnailImage = newCGImageRef;不会导致它触发键/值观察事件,并且永远不会调用observeValueForKeyPath:...

我使用同一个类的另一个属性(BOOL)测试了代码,它对那个属性来说效果很好。这不也适用于上面的房产吗?

注意:我尝试手动设置属性([self setValue:newValue forKey:@"thumbnailImage"],导致以下错误:

setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key thumbnailImage.

1 个答案:

答案 0 :(得分:4)

__attribute__((NSObject))告诉编译器将结构指针视为对象,因此这允许您保留/释放对象(通常用于块)。此属性对CFImageRef是结构指针的事实没有影响,并且KVC不会自动换行结构指针,尽管它会包装结构。要解决您的问题,您需要在未定义的键上截取KVC以设置和返回正确的对象,或者只使用UIImage

KVC Documentation:

  

自动包装和展开不仅限于NSPoint,NSRange,   NSRect和NSSize结构类型(即Objective-C的类型)   类型编码字符串以{)开头可以包装在NSValue中   对象

<强> TestCF_KVC.h

#import <Foundation/Foundation.h>

typedef struct
{
    int x, y, z;
} AStruct;

@interface TestCF_KVC : NSObject {}

@property (nonatomic, retain) NSString *text;
@property (nonatomic, assign) AStruct aStruct;
@property (nonatomic, retain) __attribute__((NSObject)) CFStringRef cftext;

-(void)test;

@end

<强> TestCF_KVC.m

#import "TestCF_KVC.h"

@implementation TestCF_KVC

@synthesize text, aStruct, cftext;

-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    NSLog(@"undefined key set for %@", key);
    if([key isEqualToString:@"cftext"])
    {
        self.cftext = (CFStringRef)value;
    }
    else
    {
        [super setValue:value forUndefinedKey:key];
    }
}

-(id)valueForUndefinedKey:(NSString *)key
{
    NSLog(@"undefined key get for %@", key);
    if([key isEqualToString:@"cftext"])
    {
        return (NSString*)self.cftext;
    }

    return [super valueForUndefinedKey:key];
}

-(void)test
{
    NSString *txt = @"text worked";
    AStruct astr = { .x=1, .y=5, .z=10 };
    CFStringRef cftxt = (CFStringRef)@"cftext worked";

    //Test a normal NSString for KVC
    [self setValue:txt forKey:@"text"];
    txt = [self valueForKey:@"text"];
    NSLog(@"text[%s]: %@", @encode(NSString), [self valueForKey:@"text"]);

    //Test a struct for KVC
    NSValue *value = [NSValue value:&astr withObjCType:@encode(AStruct)];
    [self setValue:value forKey:@"aStruct"];
    [[self valueForKey:@"aStruct"] getValue:&astr];
    NSLog(@"aStruct[%s]: %d %d %d", @encode(AStruct), aStruct.x, aStruct.y, aStruct.z);

    //Test a Core Foundation type for KVC
    [self setValue:(NSString*)cftxt forKey:@"cftext"];
    cftxt = (CFStringRef)[self valueForKey:@"cftext"];
    NSLog(@"cftext[%s]: %@", @encode(CFStringRef), (NSString*)cftxt);
}

@end

来自呼叫测试的日志输出:

text[{NSString=#}]: text worked
aStruct[{?=iii}]: 1 5 10
undefined key set for cftext
undefined key get for cftext
cftext[^{__CFString=}]: cftext worked