我的项目使用iCloud实现核心数据同步。当我尝试删除重复项时,会出现以下异常:- [NSFunctionExpression _propertyType]:向实例发送未识别的选择器。
我已经了解到这种问题的主要原因是在不同线程上使用相同的托管对象上下文。然而,在我的情况下,所有进程都在主线程上完成。我不知道如何解决这个问题。
在初始化方法中,我添加了以下观察者:
我已经了解到这种问题的主要原因是在不同线程上使用相同的托管对象上下文。然而,在我的情况下,所有进程都在主线程上完成。我不知道如何解决这个问题。
在初始化方法中,我添加了以下观察者:
[[NSNotificationCenter defaultCenter] addObserverForName:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:self.managedObjectContext.persistentStoreCoordinator
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSLog(@"NSPersistentStoreDidImportUbiquitousContentChangesNotification received");
[self.managedObjectContext performBlock:^{
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
[self filterDuplicates]; <-- Here I call method to call filtering duplicates
}];
}];
重复方法:
- (void) filterDuplicates {
NSString *uniquePropertyKey = @"name";
NSString *entityName = @"SFGallery";
NSExpression *countExpression = [NSExpression expressionWithFormat:@"count:(%@)", uniquePropertyKey];
NSExpressionDescription *countExpressionDescription = [[NSExpressionDescription alloc] init];
[countExpressionDescription setName:@"count"];
[countExpressionDescription setExpression:countExpression];
[countExpressionDescription setExpressionResultType:NSInteger64AttributeType];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
NSAttributeDescription *uniqueAttribute = [[entity attributesByName] objectForKey:uniquePropertyKey];
// Fetch the number of times each unique value appears in the store.
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName];
fetchRequest.propertiesToFetch = @[uniqueAttribute, countExpression];
fetchRequest.propertiesToGroupBy = @[uniqueAttribute];
fetchRequest.resultType = NSDictionaryResultType;
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES]];
NSArray *fetchedDictionaries = [self fetchAlbumsWithFetchRequest:fetchRequest];
// Filter out unique values that have no duplicates.
NSMutableArray *valuesWithDupes = [NSMutableArray array];
for (NSDictionary *dict in fetchedDictionaries) {
NSNumber *count = dict[@"count"];
if ([count integerValue] > 1) {
[valuesWithDupes addObject:dict[uniquePropertyKey]];
}
}
NSFetchRequest *dupeFetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName];
dupeFetchRequest.includesPendingChanges = NO;
dupeFetchRequest.fetchBatchSize = 20;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN (%@)", valuesWithDupes];
dupeFetchRequest.predicate = predicate;
NSArray *dupes = [self fetchAlbumsWithFetchRequest:dupeFetchRequest];
SFGallery *prevObject;
for (SFGallery *duplicate in dupes) {
if (prevObject) {
if ([duplicate.name isEqualToString:prevObject.name]) {
if ([duplicate.timestamp compare:prevObject.timestamp] == NSOrderedAscending) {
[self.managedObjectContext deleteObject:duplicate];
} else {
[self.managedObjectContext deleteObject:prevObject];
prevObject = duplicate;
}
} else {
prevObject = duplicate;
}
} else {
prevObject = duplicate;
}
}
}
异常发生时要采取的方法:
- (NSArray *)fetchAlbumsWithFetchRequest:(NSFetchRequest *)fetchRequest {
Exception Here ---> NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error]) {
NSLog(@"Error when fetching Albums: %@", [error userInfo]);
return nil;
}
return fetchedResultsController.fetchedObjects;
}
需要帮助吗?
编辑 1:
我相当确定它与 NSFetchRequest 相关。NSFetchRequest 的实例已经设置了属性属性:
fetchRequest.propertiesToFetch = @[uniqueAttribute, countExpression];
而这就是导致问题的 countExpression
。
在异常断点上,我记录了获取请求对象,并得到以下结果:
<NSFetchRequest: 0x10c58b4a0> (entity: SFGallery; predicate: ((null)); sortDescriptors: ((
"(timestamp, descending, compare:)"
)); type: NSDictionaryResultType; includesPendingChanges: NO; propertiesToFetch: ((
"(<NSAttributeDescription: 0x10c56e5c0>), name title, isOptional 1, isTransient 0, entity SFGallery, renamingIdentifier title, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)",
"count:(\"title\")"
)); propertiesToGroupBy: ((
"(<NSAttributeDescription: 0x10c56e5c0>), name title, isOptional 1, isTransient 0, entity SFGallery, renamingIdentifier title, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)"
)); )
这是抛出调用堆栈:
0 CoreFoundation 0x0000000103692495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001033ca99e objc_exception_throw + 43
2 CoreFoundation 0x000000010372365d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000103683d8d ___forwarding___ + 973
4 CoreFoundation 0x0000000103683938 _CF_forwarding_prep_0 + 120
5 CoreData 0x0000000100d7812d -[NSFetchRequest _newValidatedProperties:groupBy:error:] + 541
6 CoreData 0x0000000100d0da63 -[NSFetchRequest(_NSInternalMethods) _resolveEntityWithContext:] + 179
7 CoreData 0x0000000100e03c2b -[NSFetchedResultsController initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:] + 555
8 myAppli 0x000000010003d2d3 -[SFCoreDataManager fetchAlbumsWithFetchRequest:] + 163
9 myAppli 0x000000010003c901 -[SFCoreDataManager filterDuplicates] + 1073
10 myAppli 0x00000001000271cb -[SFDebugViewController removeDuplicates:] + 91
11 UIKit 0x0000000101d0af06 -[UIApplication sendAction:to:from:forEvent:] + 80
12 UIKit 0x0000000101d0aeb4 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 17
13 UIKit 0x0000000101de7880 -[UIControl _sendActionsForEvents:withEvent:] + 203
14 UIKit 0x0000000101de6dc0 -[UIControl touchesEnded:withEvent:] + 530
15 UIKit 0x0000000101d41d05 -[UIWindow _sendTouchesForEvent:] + 701
16 UIKit 0x0000000101d426e4 -[UIWindow sendEvent:] + 925
17 UIKit 0x0000000101d1a29a -[UIApplication sendEvent:] + 211
18 UIKit 0x0000000101d07aed _UIApplicationHandleEventQueue + 9579
19 CoreFoundation 0x0000000103621d21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
20 CoreFoundation 0x00000001036215f2 __CFRunLoopDoSources0 + 242
21 CoreFoundation 0x000000010363d46f __CFRunLoopRun + 767
22 CoreFoundation 0x000000010363cd83 CFRunLoopRunSpecific + 467
23 GraphicsServices 0x000000010482cf04 GSEventRunModal + 161
24 UIKit 0x0000000101d09e33 UIApplicationMain + 1010
25 myAppli 0x0000000100010473 main + 115
26 libdyld.dylib 0x0000000103ea55fd start + 1
27 ??? 0x0000000000000001 0x0 + 1
编辑2:
当我遇到以下异常时:
[NSFunctionExpression _propertyType]:向实例0x10c433d90发送了未识别的选择器
在使用 po [0x10c433d90 class]
命令打印实例后,我得到了 NSFunctionExpression
。
[myPtr class]
的值,以查看输入问题序列的值是否与您认为的类匹配。 - Hot LickscountExpressionDescription
,这对我来说有些奇怪。我猜countExpression
的实际类型是NSFunctionExpression。 - Hot Licks