ALL 或 ANY 运算符的左侧必须是 NSArray 或 NSSet
Posted
技术标签:
【中文标题】ALL 或 ANY 运算符的左侧必须是 NSArray 或 NSSet【英文标题】:The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet 【发布时间】:2014-06-17 17:03:57 【问题描述】:我刚刚接管的应用程序随机崩溃,并出现“”错误。
崩溃时的应用程序正在尝试从 Core Data 中读取数据。它不会一直崩溃,只是随机崩溃。我不确定它是导致问题的 PREDICATE 还是两个线程访问核心数据?如果它是 PREDICATE,我会认为它每次都会崩溃。他们已经对 db 结构进行了几次迁移,所以也许其中一次迁移使对象处于一种奇怪的状态,并且当 Core Data 获取该对象时它会崩溃?
这里是谓词调用
+(NSString *)buildCompoundContainsStringForField:(NSString *)field searchTerm:(NSString *)search operator:(NSString *)operator
NSArray *parts = [search componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *partJoin = [NSString stringWithFormat:@"'%@ %@ contains[c]'", operator, field];
NSString *compoundContains = [parts componentsJoinedByString:partJoin];
NSString *predicateString = [NSString stringWithFormat:@"%@ contains[c] '%@'", field, compoundContains];
return predicateString;
NSPredicate *titleSearch = [AStore searchTitlePredicate:search];
NSPredicate *ingredientSearch = [AStore searchIngredientsPredicate:search];
NSPredicate *recipeDecription = [AStore searchDescriptionPredicate:search];
NSPredicate *searchMethod = [AStore searchMethodPredicate:search];
+ (NSPredicate *)searchIngredientsPredicate:(NSString *)search
return [NSPredicate predicateWithFormat:[self buildCompoundContainsStringForField:@"ANY ingredients.desc"
searchTerm:search
operator:@"AND"]];
+ (NSPredicate *)searchTitlePredicate:(NSString *)search
return [NSPredicate predicateWithFormat:[self buildCompoundContainsStringForField:@"ANY title"
searchTerm:search
operator:@"AND"]];
+ (NSPredicate *)searchDescriptionPredicate:(NSString *)search
return [NSPredicate predicateWithFormat:[self buildCompoundContainsStringForField:@"ANY recipeDescription"
searchTerm:search
operator:@"AND"]];
+ (NSPredicate *)searchMethodPredicate:(NSString *)search
return [NSPredicate predicateWithFormat:[self buildCompoundContainsStringForField:@"ANY method"
searchTerm:search
operator:@"AND"]];
=== 崩溃的方法 ======
-(void) updateDictionaryWithWeight:(int)weight usingRequest:(NSFetchRequest *)request
NSError *error;
NSArray *results = [self.context executeFetchRequest:request error:&error]; <---- CRASHES/ERRORS HERE
......
=== 这里是调用栈 ====
*** First throw call stack:
(
0 CoreFoundation 0x0000000103fbb495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000103d1a99e objc_exception_throw + 43
2 Foundation 0x000000010351606b -[NSPredicateOperator performOperationUsingObject:andObject:] + 826
3 Foundation 0x0000000103515c1e -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 314
4 Foundation 0x0000000103515ae2 -[NSPredicate evaluateWithObject:] + 19
5 CoreData 0x0000000101df40aa -[NSManagedObjectContext executeFetchRequest:error:] + 2170
6 CoreData 0x0000000101e3b18b -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] + 395
7 CoreData 0x0000000101ea5ed3 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 563
8 libdispatch.dylib 0x00000001042ef72d _dispatch_client_callout + 8
9 libdispatch.dylib 0x00000001042de5d0 _dispatch_barrier_sync_f_invoke + 57
10 CoreData 0x0000000101e3af92 _perform + 114
11 CoreData 0x0000000101e3ae2d -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] + 301
12 CoreData 0x0000000101df3a21 -[NSManagedObjectContext executeFetchRequest:error:] + 497
13 Things 0x000000010035ff40 -[AStore updateDictionaryWithWeight:usingRequest:] + 128
14 Things 0x000000010035cce8 -[AStore weightedThingsWithSearchString:andFilterFlags:sortedBy:] + 920
15 Things 0x00000001003b87a7 -[ASearchViewController doSearchWithCompletionBlock:] + 1319
16 Things 0x00000001003be466 -[ASearchViewController localRefresh:] + 198
17 Things 0x00000001003c17e1 __59-[ASearchViewController filterControllerDidFinish:]_block_invoke + 577
18 Things 0x000000010059624e __72+[UIView(mfw) presentIndicatorWithLoadingTitle:successTitle:completion:]_block_invoke + 174
19 libdispatch.dylib 0x00000001042dc851 _dispatch_call_block_and_release + 12
20 libdispatch.dylib 0x00000001042ef72d _dispatch_client_callout + 8
21 libdispatch.dylib 0x00000001042df3fc _dispatch_main_queue_callback_4CF + 354
22 CoreFoundation 0x0000000104019289 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
23 CoreFoundation 0x0000000103f66854 __CFRunLoopRun + 1764
24 CoreFoundation 0x0000000103f65d83 CFRunLoopRunSpecific + 467
25 GraphicsServices 0x0000000104b2bf04 GSEventRunModal + 161
26 UIKit 0x0000000102493e33 UIApplicationMain + 1010
27 Things 0x0000000100002463 main + 115
28 libdyld.dylib 0x00000001045405fd start + 1
29 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
【问题讨论】:
包含“ALL 或 ANY 运算符”的谓词是什么样的? 您创建了几个谓词(使用未知方法,如 buildCompoundContainsStringForField),因此(对我而言)不清楚哪个谓词或获取请求导致崩溃。 - 也许您可以在崩溃发生时在调试器控制台中设置“异常断点”然后po request
。此外,有关实体和关系的信息也会很有用。
它是由 TITLE 谓词引起的,它是 ANY title CONTAINS[c] "sh" 也会更新原始帖子并包含该方法。
最可能的原因是“title”是一对一的关系。 “ANY”只能用于一对多关系。
您找到解决方案了吗?我遇到了完全相同的问题。
【参考方案1】:
问题是这里不需要 ANY 运算符。正如 Martin R 提到的,ANY 用于多对多关系。所以如果你有类似的东西:
class Recipe
public String title;
class CookBook
public Array recipes;
如果你想找到所有具有特定标题的食谱的食谱,那么你可以使用谓词:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY recipes.title CONTAINS[c] %@", @"sh"];
如果您只需要与您的标题匹配的所有 Recipe 对象,则不需要 ANY 运算符。只需使用:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title CONTAINS[c] %@", @"sh"];
如果您想要更深入的解释,请阅读:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Predicates.pdf
特别要注意“使用带有键路径的谓词”部分。希望这会有所帮助。
【讨论】:
很好解释,我在这里有一个查询,假设标题(一个)有一系列的收据(很多),在这种情况下,我们是否需要有 ANY,因为我也面临在这种情况下使用 ANY 时很少发生崩溃 (@"ANY title.recipes.@count > 0") 很奇怪。我使用更新谓词以过滤结果的搜索字段犯了这个错误。我有“任何名称都包含 [c] %@”。这在大多数情况下都有效,但在文本搜索中使用数字搜索时尤其崩溃。摆脱任何修复它...以上是关于ALL 或 ANY 运算符的左侧必须是 NSArray 或 NSSet的主要内容,如果未能解决你的问题,请参考以下文章