Ich habe Probleme mit Core Data, die ich nicht lösen kann. Ich habe auf dem harten Weg über Nebenläufigkeitsprobleme in Core Data erfahren, daher bin ich sehr vorsichtig und führe nur irgendwelche Kerndatenoperationen in performBlock:
und performBlockAndWait:
Blöcken durch.Core Data Deadlocking beim Ausführen von Abrufanforderungen innerhalb von performBlockAndWait Blöcke
geht hier meinen Code:
/// Executes a fetch request with given parameters in context's block.
+ (NSArray *)executeFetchRequestWithEntityName:(NSString *)entityName
predicate:(NSPredicate *)predicate
fetchLimit:(NSUInteger)fetchLimit
sortDescriptor:(NSSortDescriptor *)sortDescriptor
inContext:(NSManagedObjectContext *)context{
NSCAssert(entityName.length > 0,
@"entityName parameter in executeFetchRequestWithEntityName:predicate:fetchLimit:sortDescriptor:inContext:\
is invalid");
__block NSArray * results = nil;
NSPredicate * newPredicate = [CWFCoreDataUtilities currentUserPredicateInContext:context];
if (predicate){
newPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[newPredicate, predicate]];
}
[context performBlockAndWait:^{
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.fetchLimit = fetchLimit;
request.predicate = newPredicate;
if (sortDescriptor) {
request.sortDescriptors = @[sortDescriptor];
}
NSError * error = nil;
results = [context executeFetchRequest:request error:&error];
if (error){
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:@"Fetch requests are required to succeed."
userInfo:@{@"error":error}];
NSLog(@"ERROR! %@", error);
}
NSCAssert(results != nil, @"Fetch requests must succeed");
}];
return results;
}
Wenn ich diese Methode gleichzeitig von zwei verschiedenen Threads eingeben und zwei unterschiedliche Kontexte passieren, ich in einer Sackgasse auf dieser Reihe führen: results = [context executeFetchRequest:request error:&error];
was interessant ist: Es scheint, als könnten beide Threads keine Sperre für den Persistent Store Coordinator erhalten, um eine Abrufanforderung auszuführen.
Alle meine Kontexte sind NSPrivateQueueConcurrencyType
.
Ich kann nicht sagen, warum schließe ich die App und was soll ich anders machen. Meine Nachforschungen zu Stack Overflow gaben mir nichts, da die meisten Leute alle Sperren durch das Absetzen der Abrufanforderungen in der MOC-Warteschlange behoben haben, was ich bereits getan habe.
Ich werde alle Informationen zu diesem Thema zu schätzen wissen. Fühlen Sie sich frei, Dokumentationslinks und andere lange Lesevorgänge zu bieten: Ich bin begierig, mehr über alle Arten von Nebenläufigkeitsproblemen und -strategien zu lernen.
Könnten Sie Code vorsehen: 'currentUserPredicateInContext:' und 'predicate' Konstruktion (verwenden sie Objekt aus anderen Kontexten konstruiert werden)? –
Sind Sie sicher, dass es ein Deadlock ist? Ich schlage vor, Sie die Stack-Spuren der Threads Post –
@DanShelly Der Bug ist sehr schwer zu reproduzieren, ich habe es heute nicht gefangen, also keine Stack-Spuren. Prädikate haben das Format "owner =% @", wobei% @ eine Zeichenfolge aus Benutzerstandardwerten ist. Ich habe überhaupt keine MObjects in Prädikaten verwendet. Ich bin sicher, es ist ein Deadlock, da in den Stack-Traces zwei meiner Threads auf mutex_wait hängen bleiben, was aus einem Aufruf von executeFetchRequest resultiert. –