проверить идентификатор isKindOfType CFType - PullRequest
3 голосов
/ 17 ноября 2011

Коротко: как определить , является ли идентификатор CFType или нет во время выполнения

Я реализую атрибуты динамических данных ядра и в методе willSave ExtendedManagedObject я хочу проверить, является ли значение id CFType, чтобы сохранить его в файле plist.

Если я пытаюсь сохранить в plist UIImage, который не является бесплатным по мосту с CF ( apple docs ), я получаю сообщение об ошибке:

2011-11-17 17: 16: 25.294 [490: 707] Ошибка сохранения расширенных данных: список свойств недопустим для формата (списки свойств не могут содержать объекты типа 'CFType')

Могу ли я проверить это каким-либо методом или я должен реализовать сам (просто 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];
}

Ответы [ 2 ]

7 голосов
/ 17 ноября 2011

Это неправильный подход к проблеме. Сообщение в блоге, на которое вы ссылаетесь, сохраняет расширенные атрибуты в виде сериализованного списка. Список может содержать только следующие типы объектов, как написано в официальном документе :

NSArray, NSDictionary, NSDate, NSData, NSString и NSNumber.

Другие занятия просто запрещены. Не добавляйте объекты любого другого класса в атрибуты, расширенные таким образом.

Кроме того, сохранение файла изображения в базе данных CoreData не является хорошей идеей, вообще говоря, прочитайте О BLOB-объектах в официальном документе. Вместо этого сохраните UIImage в файле и запишите путь к файлу в базе данных CoreData.


Если у вас просто есть временное свойство, которое не сохраняется в базе данных, вам даже не придется создавать расширенные атрибуты. Просто добавьте его как свойство подкласса NSManagedObject:

@interface MyManagedObject: NSManagedObject {
}
@property(retain, nonatomic) UIImage* thumbnail;
@property(retain, nonatomic) NSDictionary* thumbnailDictionary;
@end

без добавления thumbnail в модели CoreData. Затем выполните соответствующий @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 ...
}

Уродливое предложение if существует потому, что нет общедоступной функции, которая дает вам CFTypeID объекта Objective-C без мостов. Прочитайте ссылку CFType . Но я не рекомендую делать это.

0 голосов
/ 27 марта 2012

Попытка сохранить изображение в формате UIImage также приводит к тому, что "списки свойств не могут содержать объекты типа CFType error. Лучший способ - преобразовать UIImage в NSData перед записью в pList.

...