Cocoa 带核心数据的中断多线程
这是先前一个问题的一个更好的聚焦版本,该问题涉及一个与以前完全不同的主题 我正在开发一个具有多线程的Cocoa核心数据应用程序。有一首歌和一位艺术家;每首歌都有艺术家的关系。此处未引用代表代码文件;它或多或少看起来像是XCode生成的模板 我使用前一种技术比使用后一种技术要好得多,而且任何多线程功能都来自核心数据模板。当我用一种方法完成所有ManagedObjectContext工作时,我很好。当我将fetch或insert然后return对象工作放入一个单独的方法中时,应用程序会在新方法的return语句处停止(但不会崩溃),如下所示。新的方法甚至有自己的MOC是安全的,而且没有任何帮助。结果是歌曲中添加了一个元素,并在生成艺术家后停止 我没有错误或异常,我也不知道为什么。我已经调试好了wazoo。我的理论是,发生的任何错误都在另一个线程中,而我正在观看的线程永远都在等待某些东西 getArtistObject:有什么问题,如何修复?谢谢Cocoa 带核心数据的中断多线程,cocoa,multithreading,core-data,Cocoa,Multithreading,Core Data,这是先前一个问题的一个更好的聚焦版本,该问题涉及一个与以前完全不同的主题 我正在开发一个具有多线程的Cocoa核心数据应用程序。有一首歌和一位艺术家;每首歌都有艺术家的关系。此处未引用代表代码文件;它或多或少看起来像是XCode生成的模板 我使用前一种技术比使用后一种技术要好得多,而且任何多线程功能都来自核心数据模板。当我用一种方法完成所有ManagedObjectContext工作时,我很好。当我将fetch或insert然后return对象工作放入一个单独的方法中时,应用程序会在新方法的re
- (void)main
{
NSInteger songCount = 1;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
/* songDict generated here */
for (id key in songDict)
{
NSManagedObject *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:moc];
[song setValue:[songDictItem objectForKey:@"Name"] forKey:@"title"];
[song setValue:[self getArtistObject:(NSString *) [songDictItem objectForKey:@"Artist"]] forKey:@"artist"];
[songDictItem release];
songCount++;
}
NSError *error;
if (![moc save:&error])
[NSApp presentError:error];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc];
[moc release], moc = nil;
[[self delegate] importDone];
}
- (NSManagedObject*) getArtistObject:(NSString*)theArtist
{
NSError *error = nil;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:moc];
[fetch setEntity:entityDescription];
// object to be returned
NSManagedObject *artistObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
// set predicate (artist name)
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name = \"%@\"", theArtist]];
[fetch setPredicate:pred];
NSArray *response = [moc executeFetchRequest:fetch error:&error];
if (error)
[NSApp presentError:error];
if ([response count] == 0) // empty resultset --> no artists with this name
{
[artistObject setValue:theArtist forKey:@"name"];
NSLog(@"%@ not found. Adding.", theArtist);
return artistObject;
}
else
return [response objectAtIndex:0];
}
@end
尝试在访问托管对象上下文之前锁定它,并在使用完毕后再次解锁它:
- (void)main
{
NSInteger songCount = 1;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc lock];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
/* songDict generated here */
for (id key in songDict)
{
[moc lock];
NSManagedObject *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:moc];
[moc unlock];
[song setValue:[songDictItem objectForKey:@"Name"] forKey:@"title"];
[song setValue:[self getArtistObject:(NSString *) [songDictItem objectForKey:@"Artist"]] forKey:@"artist"];
[songDictItem release];
songCount++;
}
NSError *error;
[moc lock];
if (![moc save:&error])
[NSApp presentError:error];
[moc unlock];
[moc lock];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
[moc release], moc = nil;
[[self delegate] importDone];
}
- (NSManagedObject*) getArtistObject:(NSString*)theArtist
{
NSError *error = nil;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc lock];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
[moc lock];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:moc];
[moc unlock];
[fetch setEntity:entityDescription];
// object to be returned
[moc lock];
NSManagedObject *artistObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
[moc unlock];
// set predicate (artist name)
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name = \"%@\"", theArtist]];
[fetch setPredicate:pred];
[moc lock];
NSArray *response = [moc executeFetchRequest:fetch error:&error];
[moc unlock];
if (error)
[NSApp presentError:error];
if ([response count] == 0) // empty resultset --> no artists with this name
{
[artistObject setValue:theArtist forKey:@"name"];
NSLog(@"%@ not found. Adding.", theArtist);
return artistObject;
}
else
return [response objectAtIndex:0];
}
@end
尝试在访问托管对象上下文之前锁定它,并在使用完毕后再次解锁它:
- (void)main
{
NSInteger songCount = 1;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc lock];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
/* songDict generated here */
for (id key in songDict)
{
[moc lock];
NSManagedObject *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song" inManagedObjectContext:moc];
[moc unlock];
[song setValue:[songDictItem objectForKey:@"Name"] forKey:@"title"];
[song setValue:[self getArtistObject:(NSString *) [songDictItem objectForKey:@"Artist"]] forKey:@"artist"];
[songDictItem release];
songCount++;
}
NSError *error;
[moc lock];
if (![moc save:&error])
[NSApp presentError:error];
[moc unlock];
[moc lock];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
[moc release], moc = nil;
[[self delegate] importDone];
}
- (NSManagedObject*) getArtistObject:(NSString*)theArtist
{
NSError *error = nil;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc lock];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
[moc unlock];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
[moc lock];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:moc];
[moc unlock];
[fetch setEntity:entityDescription];
// object to be returned
[moc lock];
NSManagedObject *artistObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
[moc unlock];
// set predicate (artist name)
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name = \"%@\"", theArtist]];
[fetch setPredicate:pred];
[moc lock];
NSArray *response = [moc executeFetchRequest:fetch error:&error];
[moc unlock];
if (error)
[NSApp presentError:error];
if ([response count] == 0) // empty resultset --> no artists with this name
{
[artistObject setValue:theArtist forKey:@"name"];
NSLog(@"%@ not found. Adding.", theArtist);
return artistObject;
}
else
return [response objectAtIndex:0];
}
@end
您不能锁定NSManagedObjects 您无法锁定NSManagedObjects 不行。它仍然点击“返回artistObject;”然后停下来。有趣的是,如果我多次单击触发此操作的按钮,它每次都会对第一首歌曲/艺术家重复相同的操作。有没有一种方法可以使用调试器来找出它在等待什么(如果有的话)?我不知道,但希望其他人可以加入。没有。它仍然点击“返回artistObject;”然后停下来。有趣的是,如果我多次单击触发此操作的按钮,它每次都会对第一首歌曲/艺术家重复相同的操作。有没有一种方法可以使用调试器来找出它在等待什么(如果有的话)?我不知道,但希望其他人可以加入。