我有一个具有如下属性定义的类:
// 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.
答案 0 :(得分:4)
__attribute__((NSObject))
告诉编译器将结构指针视为对象,因此这允许您保留/释放对象(通常用于块)。此属性对CFImageRef
是结构指针的事实没有影响,并且KVC不会自动换行结构指针,尽管它会包装结构。要解决您的问题,您需要在未定义的键上截取KVC以设置和返回正确的对象,或者只使用UIImage
。
自动包装和展开不仅限于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