2010-08-31 105 views
2

這裏有一個小背景:將UIImage保存爲核心數據正在使用RAM。嘿?

我在覈心數據中存儲相當大的圖像(900x1200像素)。這些來自UIImagePickerView,我裁剪並將它們調整爲合理的大小。

我使用了一個相當標準的值轉換到UIImage的NSData的和之間的轉換(反之亦然)。

該項目工程,但它最終得到內存警告,然後被終止。

如果我刪除寫出的圖像核心數據線,問題消失(但我需要存儲這些圖片!)

當我運行儀器「分配」顯示的預期峯值時的圖像選擇器返回全分辨率圖像,並調整它的大小。轉型完成後,我從5到22 megs並回到5。

分配永遠不會顯示更多的增長。

我有一個大約200字節的泄漏,我幾乎積極是無關的,但我提到它的全部披露。

現在,當我使用內存監視器工具時,我發現我的應用程序的「真實內存」每次保存其中一個圖像時增加5 megs。

因此,任何幫助(或想法)將不勝感激!

爲什麼Allocations不顯示這種增長,但內存監視器呢?這是一個線索嗎?

起初我以爲是因爲我的值轉換器使用了一個自動釋放池,可能沒有被排空,但後來我意識到那是當我讀取數據,而不是寫它。

下面是相關的代碼。請讓我知道,如果你有任何想法,我可以如何調試!

-Pete

這裏是我的價值變壓器: 先在接口聲明:

@interface ImageToDataTransformer : NSValueTransformer { } 
@end 

現在執行:

@implementation ImageToDataTransformer 


+ (BOOL)allowsReverseTransformation { 
    return YES; 
} 

+ (Class)transformedValueClass { 
    return [NSData class]; 
} 

- (id)transformedValue:(id)value { 
    NSData *data = UIImagePNGRepresentation(value); 
    return data; 
} 

- (id)reverseTransformedValue:(id)value { 
    UIImage *uiImage = [[UIImage alloc] initWithData:value]; 
    return [uiImage autorelease]; 
} 

下面的代碼,我寫出來:

FieldCollectorAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 

NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

NSError *error; 
NSManagedObject *theFieldObject=nil; 

// Populate the bare necessities 

theFieldObject = [NSEntityDescription insertNewObjectForEntityForName:@"FieldObject" 
               inManagedObjectContext:context]; 

NSManagedObject *theImageObject =[NSEntityDescription insertNewObjectForEntityForName:@"ImageObject" inManagedObjectContext:context]; 

// Let's link up the two 

[theImageObject setValue:theFieldObject forKey:@"fieldObject"]; 
[theFieldObject setValue:theImageObject forKey:@"photo"]; 


[theFieldObject setValue:image forKeyPath:@"photo.Photo"]; 

// Save the context 

[context save:&error]; 

回答

4

它並沒有解決這個謎,但可能會解決您的問題(除非您有某種原因絕對需要以這種方式使用Core Data),但是您不應該使用Core Data。它的目的不是爲了存儲如此巨大的二進制數據塊。而是在Core Data中存儲對數據的引用(即文件名或URL),並使用NSDatadataWithContentsOfFilewriteToFile

+0

亞當, 你可能是正確的,它不是設計來做到這一點,這是A計劃,直到我讀另一個線程正相反。 無論如何,在我發佈這幾個小時後,我已經找到了問題!我會點擊「回答你的問題」按鈕! – VTPete 2010-08-31 03:11:39

+1

下面是在相同情況下的人員的後續行動: 我輕鬆地將我的程序轉換爲讀取/寫入/刪除圖像到文檔文件夾而不是核心數據。正如所料,寫入的性能比未緩存的讀取速度快一點。內存使用現在很好。 我對這個決定感到有點矛盾,因爲保留所有存儲在一個系統中總是比混合和匹配更好。我很想聽聽有關何時使用(而不是使用)核心數據的一些真實情況。現在我將堅持使用我管理的文件... – VTPete 2010-09-01 10:44:26

+2

使用核心數據來處理除二進制數據以外的所有內容。將二進制數據存儲在磁盤上並將其引用到Core Data中。這是在iOS上使用它的正確方式,因爲使用了緩存。 – 2010-09-01 19:32:11

2

問題是爲了性能,Core Data緩存了很多。我早就應該猜到了,因爲我寫了類似的通用數據存儲算法。這也解釋了爲什麼我沒有把它看作是我的記憶。當您將保存消息發送到託管對象上下文時,寫入的數據將被緩存。

通過使用NSManagedObjectContext消息「RefreshObject:mergeChanges:」,可以將NSManagedObjects標記爲「髒」(故障)。在將保存消息發送到上下文後,直接對該對象執行此操作。

通過使用「NO」作爲第二個參數,您說:「您需要返回到磁盤才能得到它。」

poof,我的內存使用問題得到解決。

當修復是一行代碼時,你不喜歡嗎?

-Pete