__attribute__((NSObject))
tells the compiler to treat structure pointers as an object therefore this allows you to retain/release the object (often used for blocks). This attribute has no effect on the fact that CFImageRef
is a struct pointer and KVC does not automatically wrap struct pointers though it will wrap structs. To solve your issue you will need to intercept KVC on undefined keys to set and return the correct object, or just use UIImage
instead.
KVC Documentation:
Automatic wrapping and unwrapping is not confined to NSPoint, NSRange,
NSRect, and NSSize—structure types (that is, types whose Objective-C
type encoding strings start with {) can be wrapped in an NSValue
object.
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
Log Output From Calling -test:
text[{NSString=#}]: text worked
aStruct[{?=iii}]: 1 5 10
undefined key set for cftext
undefined key get for cftext
cftext[^{__CFString=}]: cftext worked