gpt4 book ai didi

objective-c - 使用 deleteObject : on Core Data store 时的 EXC_BAD_ACCESS (SIGSEGV)

转载 作者:太空狗 更新时间:2023-10-30 03:47:48 26 4
gpt4 key购买 nike

在我的应用程序中,我要从两个核心数据存储中删除(或尝试删除)所有记录,然后再添加新的记录。它们是 2 个简单的存储,包含与地址簿中的记录相关的数据(VIContacts 包含联系人 ID 和 vcard 哈希(整数),VIGroup 包含组 ID 和组名称)。

为了从商店中删除所有联系人,我在名为 -clear: 的方法中使用了这段代码:


NSArray *allOldRowsInVIContacts = [[mainContext fetchObjectsForEntityName:[VIContact name]
includePropertyValues:NO
withPredicate:nil] copy];

for (NSManagedObject *obj in allOldRowsInVIContacts) {
@try {
[mainContext deleteObject:obj];
}
@catch (NSException *exception) {
NSLog(@"Exception Triggered: %@", exception.reason);
[NSException raise:exception.reason format:@"thrown on vicontacts."];
}
}

[allOldRowsInVIContacts release];

if (![mainContext save:error]) {
return NO;
}

NSArray *allOldRowsInVIGroups = [[mainContext fetchObjectsForEntityName:[VIGroup name]
includePropertyValues:NO
withPredicate:nil] copy];

NSLog(@"all rows in VIGroups count: %d", [allOldRowsInVIGroups count]);

for (NSManagedObject *obj in allOldRowsInVIGroups) {
@try {
[mainContext deleteObject:obj];
}
@catch (NSException *exception) {
NSLog(@"Exception Triggered: %@", exception.reason);
[NSException raise:exception.reason format:@"thrown on vigroups."];
}
}

[allOldRowsInVIGroups release];

NSLog(@"at the end of -clear: Going to save context.");

/* SAVE */
if (![mainContext save:error]) {
return NO;
}

应用似乎总是在 VIGroup 区域附近崩溃。

崩溃日志如下:


Crashed Thread: 5 Dispatch queue: com.apple.root.default-priority

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
...
Thread 5 Crashed:: Dispatch queue: com.apple.root.default-priority
0 com.apple.CoreFoundation 0x00007fff82532574 __CFBasicHashRehash + 1412
1 com.apple.CoreFoundation 0x00007fff8252b41b __CFBasicHashAddValue + 75
2 com.apple.CoreFoundation 0x00007fff82531f78 CFBasicHashAddValue + 3176
3 com.apple.CoreFoundation 0x00007fff82547899 CFSetAddValue + 121
4 com.apple.CoreData 0x00007fff8520e3dc -[NSManagedObjectContext deleteObject:] + 220
5 com.andrei.AddressBookApp 0x000000010004da9a -[AddressBookFrameworkSyncHelper clear:] + 490
6 com.andrei.AddressBookApp 0x000000010004c8f9 +[AddressBookFrameworkSyncHelper saveSnapshot:] + 105
7 com.andrei.AddressBookApp 0x000000010002d417 -[SLSyncOperation main] + 2631
8 com.apple.Foundation 0x00007fff8b68dbb6 -[__NSOperationInternal start] + 684

其他信息

我已经使用 Instruments 寻找僵尸,但没有出现。应用程序中存在一些泄漏,但与 Core Data 无关。

VIGroup 和 VIContact 之间没有关系。它们是独立的独立实体。

奇怪的是,代码似乎从来没有进入@catch,因为控制台在崩溃前没有接收到任何Exception triggered: ... 消息。

错误时不时抛出。该应用程序似乎在 Lion 上更稳定,但在 Mountain Lion 和 Snow Leopard 上经常崩溃。

谢谢。非常感谢任何帮助。

更新了一些代码

创建的 MOC:

我创建了一个“NSOperation”(“SLSyncOperation”)并将其添加到“NSOperationQueue”。 SLSyncOperation 被添加到 NSOperationQueue 中:


[backgroundQueue setMaxConcurrentOperationCount:1];

// has a custom initializer
currentOperation = [[SLSyncOperation alloc] initWithPersistentStoreCoordinator:persistentStoreCoordinator
andDelegate:delegate
forceRemoteSync:forceSync];

[backgroundQueue addOperation:currentOperation];

这是 SLSyncOperation 的 main 方法(继承自 NSOperation):


- (void)main {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

syncProgressTracker = [SLSyncProgressTracker sharedProgressTracker];
syncProgressTracker.currentStatus = SLSyncStatusIdle;

// ... some other setup and sending notifications ...

/* Set up. */
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
managedObjectContext = [[NSManagedObjectContext alloc] init];

// persistentStoreCoordinator is passed from the app delegate
[managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];

// ... continues with other logic (syncing to a server), and the end of the method is: ...

/* Tear down. */
[managedObjectContext release];
managedObjectModel = nil;

[pool drain];
}

正在使用的 MOC:

我在单例类中使用 MOC,它是从 SLSyncOperation 中调用的方法调用的。我假设在这种情况下一切都发生在同一个线程中......?我将添加一些测试方法来检查这一点。

正在单例类中初始化 MOC:


+ (AddressBookFrameworkSyncHelper *)sharedHelper {
if (!_sharedAddressBookHelper) {
_sharedAddressBookHelper = [[AddressBookFrameworkSyncHelper alloc] init];
}

return _sharedAddressBookHelper;
}

- (id)init {
if (self = [super init]) {
mainContext = [(AddressBookAppAppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];
addressBookRef = [ABAddressBook sharedAddressBook];

// disable undo manager - uses less memory
[mainContext setUndoManager:nil];
}

return self;
}

在此之后,我使用 MOC (mainContext) 进行保存,将其传递给其他使用它的方法等。例如


//saving
[sharedABF.mainContext save:error];

// passing it to a Core Data method
VIContact *contactToAdd = [VIContact newOrExistingContactWithID:contactID
inContext:sharedABF.mainContext
error:error];

// that method looks like this
+ (VIContact *)newOrExistingContactWithID:(NSString *)contactID inContext:(NSManagedObjectContext *)context error:(NSError **)error {
VIContact *theContact = [[context fetchObjectsForEntityName:[VIContact name]
includePropertyValues:YES
withPredicate:
@"personID == %@", contactID] lastObject];

if (theContact) {
return [theContact retain];
} else {
// no contact found with that ID, return a new one
VIContact *newContact = [[VIContact alloc] initAndInsertInContext:context];
newContact.personID = contactID;
return newContact;
}
}

// and then fetch all rows in a Core Data entity and remove them
NSArray *allOldRowsInVIContacts = [mainContext fetchObjectsForEntityName:[VIContact name]
includePropertyValues:NO
withPredicate:nil];

for (NSManagedObject *obj in allOldRowsInVIContacts) {
[mainContext deleteObject:obj];
}

if (![mainContext save:error]) {
return NO;
}

fetchObjectsForEntityName 方法取自 here .

我将尝试查看是否使用您提到的那些方法从不同的线程访问该方法。希望这对您有所帮助,并为您提供有关我如何使用 MOC 的更多信息。

更多信息

我已将创建 mainContext 的线程命名为 SLSyncOperationThread.Name set.。在应用程序崩溃之前,我放置了一个 NSLog 来打印线程的名称。它每次都打印出该线程的名称。所以它似乎不是一个多线程问题。特别是因为应用程序在每次达到该点时时不时地崩溃。

最佳答案

尝试简单地删除文件而不是对象:

- (void)emptyDatabase{
NSError * error;
// retrieve the store URL
NSURL * storeURL = [[self.managedObjectContext persistentStoreCoordinator] URLForPersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject]];
// lock the current context
[self.managedObjectContext lock];
[self.managedObjectContext reset];//to drop pending changes
//delete the store from the current managedObjectContext
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:&error])
{
// remove the file containing the data
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
//recreate the store like in the appDelegate method
[[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];//recreates the persistent store
}
[self.managedObjectContext unlock];
}

关于objective-c - 使用 deleteObject : on Core Data store 时的 EXC_BAD_ACCESS (SIGSEGV),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12213096/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com