2011-11-17 32 views
3

不久:如何確定如果id爲CFType或者在運行時不會查身份證isKindOfType CFType

我執行dynamic core data attributes和ExtendedManagedObject的willSave方法,我想檢查id的值是CFType將其存儲到plist文件。

如果我想保存到PList UIImage的,這不是免費電話與CF(apple docs)橋接,我得到一個錯誤:

2011-11-17 17:16:25.294 [490 :707]保存擴展數據時出錯:屬性列表對於格式無效(屬性列表不能包含'CFType'類型的對象)

我可以用某種方法檢查它嗎,或者我必須自己執行它(只是來自文檔的KindOfClass)?

我不想在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]; 
} 

回答

7

這是一種解決問題的錯誤方法。您引用的博客文章將擴展屬性保存爲序列化的plist。 plist中只能包含以下類型的對象,如寫在official doc

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

其他類只是不允許的。不要將任何其他類的對象添加到以這種方式擴展的屬性中。

此外,將圖像文件保存在CoreData數據庫中不是一個好主意,一般來說,在官方文檔中將其讀取爲On Blobs。相反,將UIImage保存在一個文件中並在CoreData數據庫中寫入文件路徑。


如果你只是有一個暫時的屬性不保存到數據庫,你甚至不必經歷創建擴展屬性的麻煩。只需將其添加爲NSManagedObject子類的屬性:

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

沒有在CoreData模型添加thumbnail。然後在.m文件中執行相應的@synthesize。此屬性添加到管理對象只是沒有保存。

如果要保留未知數量的縮略圖,可以將NSDictionary(或NSArray)包含UIImage* s。


如果你確實想從一個NSObject*得到CFType,請執行下列操作:

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

謝謝你,但我想存儲指針的UIImage在運行時不添加屬性NSManagedObject子類,但只是通過 的UIImage * IMG = [[UIImage的imageWithData:loadeddata]保留]; dispatch_async(dispatch_get_main_queue(),^ { [prsn的setValue:pathToCachedFile forExtendedKey:@」 thumbnailPath「]; [cell.imageView setImage:img]; [prsn setValue:img forExtendedKey:@「thumbnailPointer」]; }); 我想跳過這種類型,同時保存到持久存儲 - (void)willSave方法。 – Renatus

+0

看到我編輯的帖子。 – Yuji

+0

>但我想在運行時存儲指向UIImage的指針而不向NSManagedObject子類添加屬性; 我也想存儲路徑到核心數據 [prsn setValue:pathToCachedFile forExtendedKey:@「thumbnailPath」]; 我只需要在運行時指向UIImage – Renatus

0

嘗試的圖像存儲在UIImage格式也導致「屬性列表不能包含類型CFType錯誤。最好的辦法是UIImage轉換爲NSData的對象寫的plist之前。