2012-06-05 56 views
0

我是一名新的iOS開發人員。希望得到幫助。 我想能夠創建許多NSManagedObjects。一個NSManagedObject的字段大小約爲5Mb。我無法在iPhone內存中保存如此大量的內存。我想將它保存在數據庫中。但是當我保存NSManagedObject時,它仍然在內存中,因爲當我保存大約20個對象時,我收到內存警告並且應用程序崩潰。 這裏是我的代碼創建NSManagedObject(大尺寸)。內存警告和應用程序崩潰

- (void)SaveItem 
    { 
     NSString *entityName = kEntityName; 
     AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
     NSManagedObjectContext *context = appDelegate.managedObjectContext; 
     NSEntityDescription *entityDesctiption = [NSEntityDescription 
                entityForName: entityName 
                inManagedObjectContext:context]; 
     // check if town exists 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id == %d", self.imageID]; 
     NSFetchRequest *requestToCheckExistense = [[NSFetchRequest alloc] init]; 
     [requestToCheckExistense setEntity:entityDesctiption]; 
     [requestToCheckExistense setPredicate:predicate]; 
     NSArray *objects = [context executeFetchRequest:requestToCheckExistense error:nil]; 
     [requestToCheckExistense release]; 
     if (objects == nil) 
     { 
      NSLog(@"there was an error"); 
     } 
     NSManagedObject *object; 
     if ([objects count] > 0) 
     { 
      // edit item 
      object = [objects objectAtIndex:0]; 
     } 
     else 
     { 
      // if object doesn't exist, find max id to imlement autoincrement 
      NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
      [request setEntity:entityDesctiption]; 
      request.propertiesToFetch = [NSArray arrayWithObjects: @"id", nil]; 
      NSArray *allobjects = [context executeFetchRequest:request error:nil]; 
      [request release]; 
      NSInteger newID = 1; 
      if ([allobjects count] > 0) 
      { 
       NSNumber *maxID = [allobjects valueForKeyPath:@"@max.id"]; 
       newID = [maxID intValue] + 1; 
      } 

      // write item 
      object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context]; 
      [object setValue:[NSNumber numberWithInt:newID] forKey:@"id"]; 
      self.imageID = newID; 
     } 
     // fill NSManagedObject 
     // size of objNSData is about 5MB 
     NSMutableData *objNSData = [[DatabaseManager sharedDatabaseManager] encryptedDataFromImage:bigImage]; 
     [object setValue:objNSData forKey:@"big"]; 

     [context save:nil]; 
    } 

當我嘗試調用[自我SaveItem] 20倍,應用程序崩潰與內存警告。當我評論了

[object setValue:objNSData forKey:@"big"]; 

一切正常。

我試着將代碼添加到@autoreleasepool,但沒有幫助。

我知道,現在,當我將數據保存到數據庫時,它仍然在iPhone內存中。如何從這個內存釋放它? 當我得到一組管理對象時,它們不在內存中(我可以輕鬆獲得100個對象,每個對象都有5Mb字段)

回答

3

在覈心數據中存儲圖像(或較大的二進制值)不是好東西選項。蘋果公司建議反對它。這是有規則的。 Check this other question/answer.

如果您想讓對象內存不足,您需要刪除所有對它們的引用。如果您在緊密循環中執行「SaveItem」,則應將每個循環執行包裝在自動釋放池中,而不是循環本身。

從蘋果的文檔,這可能是你的問題太:已經掛起的更改(插入,刪除或更新)

管理的對象由它們的上下文保留,直到它們的上下文發送保存:,復位,回滾或dealloc消息,或者撤消更改的適當數量的撤銷。 與上下文關聯的撤銷管理器保留任何更改的管理對象。缺省情況下,上下文的撤消管理器保留無限制的撤銷/重做堆棧。要限制應用程序的內存佔用量,應確保在適當的時候清理(使用removeAllActions)上下文的撤消堆棧。除非您保留上下文的撤消管理器,否則會取消其上下文。

如果您不打算使用Core Data的撤消功能,則可以通過將上下文的撤消管理器設置爲零來減少應用程序的資源需求。這可能對後臺工作線程以及大型導入或批量操作特別有利。

+0

我試過你的方法來將每個循環執行包裝在自動釋放池中。這沒有幫助。 (實際上我試圖將autorelease池放在所有可能的代碼位置,這並沒有幫助,我甚至試圖說服NSManagedObject,這也沒有幫助)。 關於撤消管理器:我試圖將其設置爲無效,這沒有幫助。 現在我將嘗試在每次[self SaveItem]調用後調用[上下文保存],重置和回滾。希望它有幫助 –

+0

是的,我在所有調用[self SaveItem]之後調用了[上下文保存],[上下文重置],[上下文保存],並且它解決了問題。謝謝。 –

相關問題