check id isKindOfType CFType

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)

Yuj*_*uji 7

这是解决问题的错误方法.您引用的博客文章将扩展属性保存为序列化plist.plist只能包含以下类型的对象,如官方文档中所述:

NSArray,NSDictionary,NSDate,NSData,NSStringNSNumber.

其他课程是不允许的.不要将任何其他类的对象添加到以这种方式扩展的属性中.

此外,将图像文件保存在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.


如果你真的想CFTypeNSObject*,请执行以下操作:

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参考.但我不建议这样做.