objective-c – 核心数据undoManager崩溃
发布时间:2020-12-16 06:59:38 所属栏目:百科 来源:网络整理
导读:我使用以下代码作为核心数据单例.以下是我的代码. (基于NachoMan的 blog.然而,代码来自他的要点. // DataManager.h#import Foundation/Foundation.h#import CoreData/CoreData.hextern NSString * const DataManagerDidSaveNotification;extern NSString * c
我使用以下代码作为核心数据单例.以下是我的代码. (基于NachoMan的
blog.然而,代码来自他的要点.
// DataManager.h #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> extern NSString * const DataManagerDidSaveNotification; extern NSString * const DataManagerDidSaveFailedNotification; @interface DataManager : NSObject { } @property (nonatomic,readonly,retain) NSManagedObjectModel *objectModel; @property (nonatomic,retain) NSManagedObjectContext *mainObjectContext; @property (nonatomic,retain) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (nonatomic,retain) NSManagedObjectContext *managedObjectContext; + (DataManager*)sharedInstance; - (BOOL)save; - (BOOL)clearEntity:(NSString *)entityDescription; - (NSManagedObjectContext*)managedObjectContext; @end // DataManager.m #import "DataManager.h" NSString * const DataManagerDidSaveNotification = @"DataManagerDidSaveNotification"; NSString * const DataManagerDidSaveFailedNotification = @"DataManagerDidSaveFailedNotification"; @interface DataManager () - (NSString*)sharedDocumentsPath; @end @implementation DataManager @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; @synthesize mainObjectContext = _mainObjectContext; @synthesize objectModel = _objectModel; @synthesize managedObjectContext = _managedObjectContext; NSString * const kDataManagerBundleName = nil;//@"AP"; NSString * const kDataManagerModelName = @"APData"; NSString * const kDataManagerSQLiteName = @"APData.sqlite"; + (DataManager*)sharedInstance { static dispatch_once_t pred; static DataManager *sharedInstance = nil; dispatch_once(&pred,^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; } - (void)dealloc { [self save]; } - (NSManagedObjectModel*)objectModel { if (_objectModel) return _objectModel; NSBundle *bundle = [NSBundle mainBundle]; if (kDataManagerBundleName) { NSString *bundlePath = [[NSBundle mainBundle] pathForResource:kDataManagerBundleName ofType:@"bundle"]; bundle = [NSBundle bundleWithPath:bundlePath]; } NSString *modelPath = [bundle pathForResource:kDataManagerModelName ofType:@"momd"]; NSLog(@"Path: %@",modelPath); _objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]]; return _objectModel; } - (NSPersistentStoreCoordinator*)persistentStoreCoordinator { if (_persistentStoreCoordinator) { NSLog(@"PersistentStore Exists %@",_persistentStoreCoordinator); return _persistentStoreCoordinator; } NSLog(@"Persistent Stored DOESN'T EXIST"); // Get the paths to the SQLite file NSString *storePath = [[self sharedDocumentsPath] stringByAppendingPathComponent:kDataManagerSQLiteName]; NSURL *storeURL = [NSURL fileURLWithPath:storePath]; // Define the Core Data version migration options NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,[NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,nil]; // Attempt to load the persistent store NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.objectModel]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Fatal error while creating persistent store: %@",error); abort(); } NSLog(@"store: %@",_persistentStoreCoordinator); return _persistentStoreCoordinator; } - (NSManagedObjectContext*)mainObjectContext { if (_mainObjectContext) return _mainObjectContext; // Create the main context only on the main thread if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(mainObjectContext) withObject:nil waitUntilDone:YES]; return _mainObjectContext; } _mainObjectContext = [[NSManagedObjectContext alloc] init]; [_mainObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; return _mainObjectContext; } - (BOOL)save { if (![self.mainObjectContext hasChanges]) return YES; NSError *error = nil; if (![self.mainObjectContext save:&error]) { NSLog(@"Error while saving: %@n%@",[error localizedDescription],[error userInfo]); [[NSNotificationCenter defaultCenter] postNotificationName:DataManagerDidSaveFailedNotification object:error]; return NO; } [[NSNotificationCenter defaultCenter] postNotificationName:DataManagerDidSaveNotification object:nil]; return YES; } - (BOOL)clearEntity:(NSString *)entityDescription { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext]; [fetchRequest setEntity:entity]; NSError *error; NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error]; for (NSManagedObject *managedObject in items) { [_managedObjectContext deleteObject:managedObject]; NSLog(@"%@ object deleted",entityDescription); } if (![_managedObjectContext save:&error]) { NSLog(@"Error deleting %@ - error:%@",entityDescription,error); return NO; } return YES; } - (NSString*)sharedDocumentsPath { static NSString *SharedDocumentsPath = nil; if (SharedDocumentsPath) return SharedDocumentsPath; // Compose a path to the <Library>/Database directory NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES) objectAtIndex:0]; SharedDocumentsPath = [libraryPath stringByAppendingPathComponent:@"Database"]; // Ensure the database directory exists NSFileManager *manager = [NSFileManager defaultManager]; BOOL isDirectory; if (![manager fileExistsAtPath:SharedDocumentsPath isDirectory:&isDirectory] || !isDirectory) { NSError *error = nil; NSDictionary *attr = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey]; [manager createDirectoryAtPath:SharedDocumentsPath withIntermediateDirectories:YES attributes:attr error:&error]; if (error) NSLog(@"Error creating directory path: %@",[error localizedDescription]); } return SharedDocumentsPath; } - (NSManagedObjectContext*)managedObjectContext { if (_managedObjectContext) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; NSUndoManager *undoManager = [[NSUndoManager alloc] init]; [_managedObjectContext setUndoManager:undoManager]; [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; [_mainObjectContext setRetainsRegisteredObjects:YES]; return _managedObjectContext; } @end 但是,如果我添加,则在managedObjectContext中 NSUndoManager *undoManager = [[NSUndoManager alloc] init]; [_managedObjectContext setUndoManager:undoManager]; 它会崩溃. Crittercism日志显示 SIGBUS 0 CoreData 0x0033d940 -[NSManagedObject(_NSInternalMethods) _newSnapshotForUndo__] + 352 1 CoreData 0x00318fb1 -[NSManagedObjectContext(_NSInternalChangeProcessing) _registerUndoForOperation:withObjects:withExtraArguments:] + 193 2 CoreData 0x0031922f -[NSManagedObjectContext(_NSInternalChangeProcessing) _registerUndoForInsertedObjects:] + 63 3 CoreData 0x003148f8 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 1384 4 CoreData 0x00314389 -[NSManagedObjectContext processPendingChanges] + 41 5 CoreData 0x002e8bd8 _performRunLoopAction + 216 6 CoreFoundation 0x0177d99e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 7 CoreFoundation 0x01714640 __CFRunLoopDoObservers + 384 8 CoreFoundation 0x016e04c6 __CFRunLoopRun + 1174 9 CoreFoundation 0x016dfd84 CFRunLoopRunSpecific + 212 10 CoreFoundation 0x016dfc9b CFRunLoopRunInMode + 123 11 GraphicsServices 0x023617d8 GSEventRunModal + 190 12 GraphicsServices 0x0236188a GSEventRun + 103 13 UIKit 0x007e2626 UIApplicationMain + 1163 14 My-App 0x284d main (main.m:16) 15 My-App 0x27b5 start + 53 当很多SO帖子说使用它时,为什么它会与这两条线路崩溃?如果我将这2行删除它不会崩溃,我只是无法使用撤消管理器. 解决方法
如果您正在寻找一种处理核心数据线程的好方法,包括在保存时通知主要上下文,MagicalRecord是一个很棒的库.除了线程帮助之外,它还为您提供简单的一行提取,简单的上下文访问等.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |