iOS崩溃与核心数据

时间:2015-04-15 14:52:19

标签: ios objective-c iphone core-data

当我在iOS 8.3中执行这行代码时,这一行崩溃了:

NSArray *results = [self executeFetchRequest:request inContext:context];

这是整个函数失败:

+ (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context
{
    [request setFetchLimit:1];

    NSArray *results = [self executeFetchRequest:request inContext:context];
    if ([results count] == 0)
    {
        return nil;
    }
    return [results objectAtIndex:0];
}

上述函数由:

调用
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{   
    NSFetchRequest *request = [self requestFirstByAttribute:attribute withValue:searchValue inContext:context];
    [request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];

    return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}

值得注意的是,我对iOS编程非常陌生,所以请放轻松我,问题可能不是最好的,可能没有太多支持代码,但这是由于我在iOS上缺乏知识。我的android问题通常比这更好:P如果我能够添加更多细节,我会尽可能多地添加,崩溃日志在下面

  

*由于未捕获的异常终止应用' NSInvalidArgumentException',原因:'错误提取请求   (NSManagedObjectResultType与内容不兼容   propertiesToFetch)'   * 第一次抛出调用堆栈:(0 CoreFoundation 0x0000000111d7dc65 exceptionPreprocess + 165 1 libobjc.A.dylib
  0x0000000110fafbb7 objc_exception_throw + 45 2 CoreData
  0x00000001112ecb6e - [NSSQLGenerator   newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:] +   1646 3 CoreData 0x00000001112d8dc4    - [NSSQLAdapter _statementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 244 4 CoreData 0x00000001111f0e0c    - [NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 316 5 CoreData 0x00000001111f0a86 - [NSSQLCore newRowsForFetchPlan:] + 118 6 CoreData 0x00000001111f033c - [NSSQLCore objectsForFetchRequest:inContext:] +   524 7 CoreData 0x00000001111efdbb    - [NSSQLCore executeRequest:withContext:error:] + 299 8 CoreData 0x00000001112caa6c __65- [NSPersistentStoreCoordinator   executeRequest:withContext:error:] _ block_invoke + 3356 9 CoreData
  0x00000001112d3c30 gutsOfBlockToNSPersistentStoreCoordinatorPerform +   192 10 libdispatch.dylib 0x0000000114e29614   _dispatch_client_callout + 8 11 libdispatch.dylib 0x0000000114e0f002 _dispatch_barrier_sync_f_invoke + 365 12 CoreData   0x00000001112c5245 _perform + 197 13 CoreData
  0x00000001111efa58 - [NSPersistentStoreCoordinator   executeRequest:withContext:error:] + 504 14 CoreData
  0x00000001111ee2ca - [NSManagedObjectContext   executeFetchRequest:error:] + 586 15 HawkExpress
  0x000000010e52438e + [NSManagedObject(MagicalRecord)   executeFetchRequest:inContext:] + 62 16 HawkExpress
  0x000000010e52446e + [NSManagedObject(MagicalRecord)   executeFetchRequestAndReturnFirstObject:inContext:] + 78 17   HawkExpress 0x000000010e5261fc   + [NSManagedObject(MagicalRecord)findFirstByAttribute:withValue:inContext:] + 140 18 HawkExpress
  0x000000010e526274 + [NSManagedObject(MagicalRecord)   findFirstByAttribute:withValue:] + 100 19 HawkExpress
  0x000000010e52aa54 + [FavouritesManager doesFavouriteExist:] + 84 20   HawkExpress 0x000000010e4de4a7    - [BookCabViewController tableView:cellForRowAtIndexPath:] + 2087 21 UIKit 0x00000001124b9a28 - [UITableView   _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 508 22 UIKit 0x0000000112498248 - [UITableView   _updateVisibleCellsNow:isRecursive:] + 2853 23 UIKit 0x00000001124ae8a9 - [UITableView layoutSubviews] + 210 24 UIKit
  0x0000000112438a2b - [UIView(CALayerDelegate)layoutSublayersOfLayer:]   + 536 25 QuartzCore 0x000000010fdfbec2 - [CALayer layoutSublayers] + 146 26 QuartzCore 0x000000010fdf06d6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE +   380 27 QuartzCore 0x000000010fdf0546   _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 28 QuartzCore 0x000000010fd5c886   _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242 29 QuartzCore 0x000000010fd5da3a   _ZN2CA11Transaction6commitEv + 462 30 QuartzCore 0x000000010fd5e0eb   _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89 31 CoreFoundation 0x0000000111cb0ca7   __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 23 32 CoreFoundation 0x0000000111cb0c00   __CFRunLoopDoObservers + 368 33 CoreFoundation 0x0000000111ca6a33 __CFRunLoopRun + 1123 34 CoreFoundation
  0x0000000111ca6366 CFRunLoopRunSpecific + 470 35图形服务
  0x0000000114a34a3e GSEventRunModal + 161 36 UIKit
  0x00000001123b8900 UIApplicationMain + 1282 37 HawkExpress
  0x000000010e4baa23 main + 99 38 libdyld.dylib
  0x0000000114e5d145 start + 1)libc ++ abi.dylib:终止于   NSException(lldb)

类型的未捕获异常

3 个答案:

答案 0 :(得分:1)

在进行计数之前,您需要检查NSArray结果是否为零。

if (array != nil) {
    NSUInteger count = [array count]; // May be 0 if the object has been deleted.
    //
}
else {
    // Deal with error.
}

请参阅https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html

答案 1 :(得分:0)

尝试将[request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];行注释掉?

'错误提取请求(NSManagedObjectResultType与propertiesToFetch的内容不兼容)'表示您似乎期望默认NSFetchRequestResultTypeNSManagedObjectResultType)。但是你要求不要获取完整的实体,而只是 ONE 属性(为什么,顺便提一下?你的方法提供了一个期望的值,只提供了一个属性来获取)。

我的解决方案:

- (id)findEntityNamed:(NSString*)entity withKeyPath:(NSString*)path equalTo:(id)value
{
    NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:entity
                                    inManagedObjectContext:context]];

    NSPredicate* predicate = 
    [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:path]
                                   rightExpression:[NSExpression expressionForConstantValue:value]
                                          modifier:NSDirectPredicateModifier
                                              type:NSEqualToPredicateOperatorType
                                           options:0];

    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchLimit:1];            // ONLY 1 OBJECT IS FETCHED!

    NSError* err = nil;
    NSArray* results = [context executeFetchRequest:fetchRequest error:&err];
    [fetchRequest release];

    if( err )
    {
        // do logging stuff etc.
    }

    if( [results count] < 1 )
        return nil;

    return [results lastObject];
}

你可以尝试这个,并告诉你这是否更像你正在寻找

答案 2 :(得分:0)

您的NSFetchRequest对象可能未正确构造。

这是一个有效的NSFetchRequest示例。通过googling&#34; NSFetchRequest示例&#34;找到更多信息。

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", aTitle]; //<----- (a)
[request setEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:moc]]; 
[request setPredicate:predicate];

注意(a),字符串必须严格遵循谓词格式字符串模式(请参阅NSPrediate类引用),name必须是托管对象模型中Person实体的属性

问题在于这部分

NSFetchRequest *request = [self requestFirstByAttribute:attribute withValue:searchValue inContext:context]; 
[request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];

所以,如果仍未解决,请发布方法[self requestFirstByAttribute ...]的代码。