2012-09-17 56 views
0

enter image description here應用程序在內存耗盡後關閉。儀器屏幕截圖

這就是我通過儀器運行我的應用程序時得到的結果。它正在處理大量的核心數據。我可以看到這顯然是不正確的,但我真的不知道這個截圖告訴我什麼。看起來是什麼問題?如果你有興趣,代碼,凝聚,是這樣的:

NSFetchRequest *oldFetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *oldEntryEntity = [NSEntityDescription entityForName:@"Entry" 
                 inManagedObjectContext:oldContext]; 

    [oldFetchRequest setEntity:oldEntryEntity]; 

    int numberOfEntries = [oldContext countForFetchRequest:oldFetchRequest error:nil]; 

    int batchSize = 4; 
    [oldFetchRequest setFetchLimit:batchSize]; 
    int offset = 0; 

    while (numberOfEntries - offset > 0) { 
     @autoreleasepool { 
     [oldFetchRequest setFetchOffset:offset]; 
     NSError *error; 
     NSArray *entries = [oldContext executeFetchRequest:oldFetchRequest error:&error]; 

     for (NSManagedObject *entry in entries) { 
     @autoreleasepool { 
      Entry *newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Entry" 
                  inManagedObjectContext:newContext]; 

      newEntry.entryID = [entry valueForKey:@"entryID"]; 

      NSMutableOrderedSet *newMediaSet = [[NSMutableOrderedSet alloc] init]; 

      NSOrderedSet *mediaSet = [entry valueForKey:@"media"]; 

      int i = 0; 

      for (NSManagedObject *media in mediaSet) { 

       Media *newMedia = [NSEntityDescription insertNewObjectForEntityForName:@"Media" 
                   inManagedObjectContext:newContext]; 

       newMedia.isInPhotoLibrary = [media valueForKey:@"isInPhotoLibrary"]; 
       newMedia.positionInEntry = [NSNumber numberWithDouble:i + 1]; 

       MediaImageData *imageData = [NSEntityDescription insertNewObjectForEntityForName:@"MediaImageData" 
                      inManagedObjectContext:newContext]; 

       imageData.data = [media valueForKey:@"originalImage"]; 

       newMedia.imageData = imageData; 

       newMedia.entry = newEntry; 
       [newMediaSet addObject:newMedia]; 

       i++; 
      } 

      newEntry.media = newMediaSet; 


     } 
     } 

     [newContext save:&error]; 

     offset = offset + batchSize; 
    } 
} 

編輯:我跟着這裏給出的建議,在@autoreleasepools(我在上面已經編輯)包裝它,之後它仍然墜毀發生這種情況:

http://cl.ly/image/1U2T2p3w1X2Z

這顯然得到了進一步推向代碼不是第一次,但它仍然崩潰。

+0

不要刪除重要的代碼。然後我們必須猜測發生了什麼。您的提取請求甚至沒有設置正確。另外,我沒有看到你添加autoreleasepool的地方......你的數據庫有多大?你的媒體集和它們包含的圖像有多大?你是否在任何地方抓住物體?你是否清除了上下文? –

+0

我已經把autoreleasepools現在。媒體集中的圖像是標準圖像的大小,我猜大約每個1mb,取決於照片。在上面的代碼之外,我沒有做任何與此有關的事情。我沒有清除上下文。 – Andrew

回答

1

嘗試在@autoreleasepool環繞快速枚舉(for循環)的內部,這應該有所幫助。當更改達到危險的內存消耗時,您還可以運行某種計數器來將環境保存在循環中。

雖然確實有很多對象,但請考慮優化數據結構。

2

不討論代碼的效率:
對於外(while)和內(for)循環,將代碼包裝在@autoreleasepool {}中。
否則,只是在外部事件循環達到循環結束時分配一大堆內存並釋放內存。

+0

謝謝,我會試一試。你能夠討論我的代碼的效率嗎?我很想知道如何讓它變得更好。 – Andrew

1

首先,發佈核心數據相關問題的一些建議。幾乎沒有太多的信息。當你忽略細節時,人們很難幫助你,因爲有太多可能的互動。

只要看看您發佈的代碼,就會留下太多問題。

我想查看按總體大小排序的信息,而不是分配數量。這將更容易地告訴你在哪裏使用內存。實際上,我無法看到那張照片中使用的記憶(舊的眼睛 - 當我放大它時,它變得太模糊)。

如果您認爲它與核心數據有關,那麼您爲什麼不運行核心數據工具?

在某些診斷幫助。

您的新MOC是否直接連接到PSC,或者是否有父級MOC?如果它有一個父MOC,那麼這些保存只會被推送到父MOC中,並且會保留在內存中直到保存被保存到數據庫。

mediaSet中有多少項目?可能有很多這樣的東西會咀嚼記憶。

您將什麼參數應用於FetchRequest和MOC?根據這些選擇,MOC可以保留物體。檢查這一點的方法是記錄每個MOC的保留/插入/刪除/等組的計數。通過記錄這些信息,你可以看到MOC是否持有你認爲不應該的東西。

然後你可以知道你是否需要刷新/重置你的MOC。

您可以作弊,並在保存後撥打電話[moc reset],但在這樣做之前/之後看到數字會很高興,因此您可以說服自己在哪裏記憶。

做更多的調試。給自己更多的信息,這樣你就可以做出正確的決定......它會給我們提供更好的信息來幫助你。

編輯

Oooops。我刪除了關於可能不是太多內存的評論。我的老眼睛沒有看到那幅圖像上的小字。

編輯

感謝。我如何記錄每個MOC的保留/插入/刪除組 的計數? - 安德魯

的MOC有幾種特性(registeredObjectsinsertedObjectsdeletedObjectsupdatedObjects),其提供一組匹配這些類別的對象。只需NSLog每個類別中對象的數量。對於每個MOC,您可以看到MOC隨着時間的推移記錄了多少個對象。

另外,啓用核心數據工具。他們真的很豐富。

+0

謝謝。我如何記錄每個MOC的保留/插入/刪除組的計數? – Andrew

相關問題