2011-11-01 161 views
10

我想在我的應用程序中實現CoreData來存儲小型數據庫。核心數據崩潰:[__NSArrayM insertObject:atIndex:]:object can not be nil

這裏我實現的:

AppDelegate.h

#import <UIKit/UIKit.h> 
#import "FavoritosViewController.h" 
#import <CoreData/CoreData.h> 

@interface XXX : NSObject <UIApplicationDelegate>{ 

    NSManagedObjectModel *managedObjectModel; 
    NSManagedObjectContext *managedObjectContext;  
    NSPersistentStoreCoordinator *persistentStoreCoordinator; 



} 
- (NSString *)applicationDocumentsDirectory; 

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

@end 

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 

    FavoritosViewController *global=[[FavoritosViewController alloc]init]; 

    global.managedObjectContext=[self managedObjectContext]; 

    . 
    . 
    . 
    } 

     - (void)applicationWillTerminate:(UIApplication *)application 
    { 
     NSError *error = nil; 
     if (managedObjectContext != nil) { 
      if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 
       /* 
       Replace this implementation with code to handle the error appropriately. 

       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
     } 

    } 

- (NSManagedObjectContext *) managedObjectContext { 

    if (managedObjectContext != nil) { 
     return managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) { 
     managedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [managedObjectContext setPersistentStoreCoordinator: coordinator]; 
    } 
    return managedObjectContext; 
} 


/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created by merging all of the models found in the application bundle. 
*/ 
- (NSManagedObjectModel *)managedObjectModel { 

    if (managedObjectModel != nil) { 
     return managedObjectModel; 
    } 
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  
    return managedObjectModel; 
} 


/** 
Returns the persistent store coordinator for the application. 
If the coordinator doesn't already exist, it is created and the application's store added to it. 
*/ 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 

    if (persistentStoreCoordinator != nil) { 
     return persistentStoreCoordinator; 
    } 

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FavoritosDatabase.sqlite"]]; 

    NSError *error = nil; 
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 

     Typical reasons for an error here include: 
     * The persistent store is not accessible 
     * The schema for the persistent store is incompatible with current managed object model 
     Check the error message to determine what the actual problem was. 
     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    }  

    return persistentStoreCoordinator; 
} 




- (NSString *)applicationDocumentsDirectory { 
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
} 

我也有xcdatamodeld 「事件」 與他們的實體屬性,Event.h ,來自它的Event.m。

在FavoritosViewController我也有所有的方法,但問題出現在所有這些之前。

它是在

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  

的應用程序崩潰並出現以下內容:

*終止應用程序由於未捕獲的異常 'NSInvalidArgumentException',原因是:「* - [__ NSArrayM insertObject:atIndex:]:object can not be nil'

An y的想法?謝謝!!!

回答

28

當我的代碼運行[NSManagedObjectModel mergedModelFromBundles:nil]時,我遇到了同樣的錯誤信息。這發生在xCode意外地撞上我之後。即使當我恢復到我的代碼的已知良好版本時,我仍然有同樣的錯誤,這是由於某種形式的腐敗。

多嘗試之後,我能夠通過退出Xcode和iPhone的模擬器,然後從以下目錄中刪除所有文件來解決問題:

$ cd /Users/john/Library/Developer/Xcode/DerivedData 

$ rm -R -f ./(folder corresponding to my project name) 

$ cd /Users/john/Library/Application Support/iPhone Simulator/5.0/Applications 

$ rm -R * 

這是能夠清除損壞的臨時文件和狀態爲模擬器,並且錯誤消失。

+1

你救了我的命。 – Snowman

+0

我不知道OP,但這絕對適合我。謝謝!我一直在尋找這個答案。 – solydest

+0

對我來說也適用,對我而言,這是重命名模型文件後發生的事情。 – PKCLsoft

-1

發生崩潰是因爲您編寫的代碼試圖在MutableArray中插入一個零。調試你的應用程序插入對象的位置,並檢查對象!= nil然後插入數組,否則NSLog(@「Object is nil」);

+0

你的意思是檢查managedObjectModel是否爲零?在 - (NSManagedObjectModel *)managedObjectModel;這已經被檢查。在這種方法失敗。 – saimonx

+0

沒有你在可變數組中插入對象的地方。崩潰是由於試圖插入一個零對象。我認爲你應該使用自我。 managedObjectContext因爲你正在使用屬性。否則,如果您將managedObjectContext傳遞給另一個類,則會發生崩潰。 –

+0

這個答案與實際問題無關。幾乎所有其他的答案都是在錢上。這不是一個可以通過更改他的代碼來解決的問題。這是由於對模型文件做了某些事情而導致的由Xcode引起的環境問題。 – PKCLsoft

-1

「我得到了類似的錯誤。但不是核心數據。我得到了陣列錯誤。所以我做了什麼插入之前只是檢查對象,並添加..」

NSMutableArray *tmpArr = [[NSMutableArray alloc] init]; 
NSString *name; 
name = @"sample"; 
if(name) 
[tmpArr addObject:name]; 
+0

它在我的xcode中工作。 – GameLoading

+0

不幸的是,這個答案沒有幫助 - 無效的調用發生在Apple的核心數據框架內;該修補程序不是有一個無效的coredata模型。 – JosephH

2

當初類似的錯誤。當您第一次在Xcode中創建模型時,似乎在內部存儲模型的名稱

我重命名了模型文件 - 這導致了OP提到的問題。

恢復模型名稱(並進行構建清理+刪除應用程序窗體設備)爲我解決了這個問題。

+0

我有這個問題,但能夠通過選擇模式的舊版本來修復它的內部參考,然後重新選擇我的新重命名版本。並重置模擬器。 –

0

我剛纔有這樣的問題。問題出在模型文件中,我有一個版本化的模型文件,不知何故當前模型版本里面沒有文件(可能是一些svn提交錯誤)。 所以我已經添加了缺少的文件,選擇它作爲當前模型,一切正常。


注意替換模型文件符兼容的設備/軟件現有的倉庫,即使是相同的(糾正我,如果我錯了,但就是那樣對我來說)。所以輕量級遷移不會工作,如果您:

  1. 有版本1和2
  2. 運行的應用和使用模式模型2
  3. 2' 代替模型文件版本2(即使有相同的字段/類型)

現有的設備/模擬器存儲不會與2' 工作,你會得到2或具有重量輕遷移打破了這些設備/ simuator儲存

6

我感動我的Model.x cdatamodeld文件到另一個文件夾,並得到這個錯誤。從乾淨的模擬器開始並沒有幫助。顯然,Xcode在某處保留對該文件的引用。

我的修復是備份我的舊Model.xcdatamodeld文件,將其從項目中刪除,在同一個文件夾中創建一個新的模型文件,然後用備份替換此文件。

+0

這爲我解決了這個問題,非常感謝! – Macondo2Seattle

1

我在重命名核心數據模型文件後發生了完全相同的錯誤。刪除Xcode/DerivedData目錄,清理項目,從模擬器中卸載應用程序,重新啓動Xcode,升級Xcode等都不起作用。

爲了讓它再次運行,我從頂部菜單中選擇了「iOS模擬器」 - >「重置內容和設置...」。

1

這裏有很多答案,但我不確定他們中的任何一個都能夠清楚地說出究竟是什麼錯誤。

我的理解是,這種崩潰的根本原因在於,您的應用安裝在設備上時,其模型爲空。例如。如果您使用iFunBox/iExplore查看設備,則會看到一個MyApp.app/MyModel.momd,它具有VersionInfo.plist,其中NSManagedObjectModel_VersionHashes字典爲空,或者NSManagedObjectModel_CurrentVersionName指向不存在的模型。

原因可能會有所不同,但基本上都與您的模型沒有在xcode中正確設置有關。在我們的例子中,項目文件與文件系統不同步,並且模型與xcode的位置不同,但是最新版本的空白也會導致它。通過從xcode中移除項目並再次添加項目,然後檢查最新版本是否正確設置,可以修復大部分這些問題。

由於這種性質的問題,從一個乾淨的狀態進行測試也很重要 - 也就是說,清理xcode中的構建文件夾(cmd-shift-option k)從設備/模擬器中刪除應用程序(否則xcode可能會讓文件處於周圍,使其看起來像事情正在工作)。

似乎有一個xcode中的錯誤(至少在xcode 4.6和5.0.1中),這意味着它在某些情況下不會發出構建警告,當它應該能夠。我已經在Apple的bugreporter中提出了這個問題,解釋爲15186008。在這種

0

的問題可能要解決:

  • 刪除應用程序在模擬器
  • 請使用cmd + alt + shift + k

然後重新生成並運行一次深層清潔你的應用。

幫助我總是在CoreData的開發階段!

0

通過從項目中刪除* .xcdatamodeld引用並重新添加它來解決該錯誤。

相關問題