Ren*_*tus 3 core-data objective-c plist
简而言之:如何在运行时确定id是否为CFType
我正在实现动态核心数据属性,并且在ExtendedManagedObject的willSave方法中,我想检查id值是否为CFType以将其存储到plist文件中.
如果我想保存到UIImage,那就不是免费的CF桥接(苹果文档),我收到一个错误:
2011-11-17 17:16:25.294 [490:707]保存扩展数据时出错:属性列表对格式无效(属性列表不能包含'CFType'类型的对象)
我可以用某种方法检查它,或者我必须自己实现(只是来自docs的isKindOfClass)?
我不想在NSManagedObject子类中实现访问器,我不知道我将从实体属性中获得多少URL.问题是关于运行时的动态扩展属性.
- (void)willSave
{
NSDictionary *changes = [self valueForKey:@"extendedChanges"];
if (changes!=nil) {
// merge changes into snapshot
NSMutableDictionary *dict = [[self extendedSnapshot] mutableCopy];
NSEnumerator *e = [changes keyEnumerator];
NSString *key;
while (key=[e nextObject]) {
id value = [changes objectForKey:key];
if (value==[NSNull null])
[dict removeObjectForKey:key];
else if (#ugly and I'm not shure is thread safe **else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSData class]] || [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]])**)
[dict setObject:value forKey:key];
}
// archive as binary plist
NSData *data = nil;
if ([dict count]>0) {
NSString *error=nil;
data = [NSPropertyListSerialization dataFromPropertyList:dict
format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];
if (error!=nil) {
NSLog(@"Error saving extended data: %@", error);
[error release];
}
}
[dict release];
[self setPrimitiveValue:data forKey:@"extendedData"];
}
[super willSave];
}
Run Code Online (Sandbox Code Playgroud)
这是解决问题的错误方法.您引用的博客文章将扩展属性保存为序列化plist.plist只能包含以下类型的对象,如官方文档中所述:
NSArray,NSDictionary,NSDate,NSData,NSString和NSNumber.
其他课程是不允许的.不要将任何其他类的对象添加到以这种方式扩展的属性中.
此外,将图像文件保存在CoreData数据库中并不是一个好主意,一般来说,请阅读官方文档中的On Blob.而是保存UIImage在文件中并在CoreData数据库中写入文件路径.
如果您只有一个未保存到数据库的瞬态属性,您甚至不必经历创建扩展属性的麻烦.只需将其添加为子类的属性NSManagedObject:
@interface MyManagedObject: NSManagedObject {
}
@property(retain, nonatomic) UIImage* thumbnail;
@property(retain, nonatomic) NSDictionary* thumbnailDictionary;
@end
Run Code Online (Sandbox Code Playgroud)
无需添加thumbnailCoreData模型.然后@synthesize 在.m文件中执行相应的操作.以这种方式添加到托管对象的属性只是没有保存.
如果你想保留未知数量的缩略图,你可以放一个NSDictionary(或NSArray)包含UIImage*s.
如果你真的想CFType从NSObject*,请执行以下操作:
NSObject* x= ...;
CFTypeID typeID=CFGetTypeID((CFTypeRef)x);
if(typeID != CFStringGetTypeID() &&
typeID != CFDateGetTypeID() &&
typeID != CFDataGetTypeID() &&
typeID != CFDictionaryGetTypeID() &&
typeID != CFArrayGetTypeID() ) {
... it's a non-plistable type ...
}
Run Code Online (Sandbox Code Playgroud)
丑陋的if子句就在那里,因为没有公共函数可以为你CFTypeID提供一个非桥接的Objective-C对象.阅读CFType参考.但我不建议这样做.