除非我先调用saveContext,否则无法识别的选择器会在核心数据中崩溃 [英] Unrecognized selector crash in Core Data unless I call saveContext first

查看:65
本文介绍了除非我先调用saveContext,否则无法识别的选择器会在核心数据中崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我代码中的三个函数:

Here are three functions from my code:

func workOutResults() {
  var fixtures = [Fixture]()

  let fixtureFetch: NSFetchRequest<Fixture> = Fixture.fetchRequest()

  do {
    fixtures = try coreDataStack.managedContext.fetch(fixtureFetch)
  } catch let error as NSError {
    print("Could not fetch. \(error), \(error.userInfo)")
  }

  for fixture in fixtures {
    // do stuff here
  }
}

func processUpdates() {
  // relevant code snippet below
  let theTable = loadLeagueTableFor(leagueName: "Championship", cds: cds)
}

func loadLeagueTableFor(leagueName: String, cds: CoreDataStack) -> [Club] {
  var leagueArray = [Club]()

  // Set up the sort descriptors 
  let pointsSortDescriptor: NSSortDescriptor = {
  let compareSelector = #selector(NSString.localizedStandardCompare(_:))
  return NSSortDescriptor(key: #keyPath(Club.leaguePoints),
                          ascending: false,
                          selector: compareSelector)
  }()

  let goalDiffSortDescriptor: NSSortDescriptor = {
  let compareSelector = #selector(NSString.localizedStandardCompare(_:))
  return NSSortDescriptor(key: #keyPath(Club.leagueGoalDiff),
                          ascending: false,
                          selector: compareSelector)
  }()

  let goalsForSortDescriptor: NSSortDescriptor = {
  let compareSelector = #selector(NSString.localizedStandardCompare(_:))
  return NSSortDescriptor(key: #keyPath(Club.leagueGoalsFor),
                          ascending: false,
                          selector: compareSelector)
  }()

  let clubNameSortDescriptor: NSSortDescriptor = {
  let compareSelector = #selector(NSString.localizedStandardCompare(_:))
  return NSSortDescriptor(key: #keyPath(Club.name),
                          ascending: true,
                          selector: compareSelector)
  }()

  // Do the Fetch request of Clubs, placing them in order into leagueArray
  let clubFetch: NSFetchRequest<Club> = Club.fetchRequest()
  clubFetch.predicate = NSPredicate(format: "%K == %@", #keyPath(Club.league.nameID), leagueName)
  clubFetch.sortDescriptors = [pointsSortDescriptor, goalDiffSortDescriptor, goalsForSortDescriptor, clubNameSortDescriptor]

  do {
    leagueArray = try cds.managedContext.fetch(clubFetch)
  } catch let error as NSError {
    print("Could not fetch. \(error), \(error.userInfo)")
  }

  cds.saveContext()

  return leagueArray
}

如果我打电话...

workOutResults()
coreDataStack.saveContext()
processUpdates()

...一切正常。但是,如果我打电话...

... everything works fine. Yet if I call...

workOutResults()
processUpdates()

...在loadLeagueTableFor()中出现以下错误:

... I get the following error in loadLeagueTableFor():

2018-01-17 19:37:38.228954+0000 Tycoon[1331:32725] -[__NSCFNumber localizedStandardCompare:]: unrecognized selector sent to instance 0xb000000000000022
2018-01-17 19:37:38.278901+0000 Tycoon[1331:32725] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber localizedStandardCompare:]: unrecognized selector sent to instance 0xb000000000000022'
*** First throw call stack:
(
0   CoreFoundation                      0x0000000104da212b __exceptionPreprocess + 171
1   libobjc.A.dylib                     0x0000000103d6ef41 objc_exception_throw + 48
2   CoreFoundation                      0x0000000104e23024 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3   CoreFoundation                      0x0000000104d24f78 ___forwarding___ + 1432
4   CoreFoundation                      0x0000000104d24958 _CF_forwarding_prep_0 + 120
5   Foundation                          0x00000001037aaad2 _NSCompareObject + 46
6   Foundation                          0x0000000103806097 _NSSortFunctionMany + 674
7   CoreFoundation                      0x0000000104d1b3bc __CFSimpleMergeSort + 124
8   CoreFoundation                      0x0000000104d1b41c __CFSimpleMergeSort + 220
9   CoreFoundation                      0x0000000104d1b41c __CFSimpleMergeSort + 220
10  CoreFoundation                      0x0000000104d1b41c __CFSimpleMergeSort + 220
11  CoreFoundation                      0x0000000104d1b2fb CFSortIndexes + 827
12  CoreFoundation                      0x0000000104d51726 CFMergeSortArray + 454
13  Foundation                          0x00000001037aa81e _sortedObjectsUsingDescriptors + 596
14  Foundation                          0x00000001037aa570 -[NSArray(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 531
15  CoreData                            0x000000010477909e -[NSManagedObjectContext executeFetchRequest:error:] + 4590
16  libswiftCoreData.dylib              0x00000001045e8f1a )
libc++abi.dylib: terminating with uncaught exception of type NSException

因此将上下文保存在两次提取之间可以避免崩溃,但会造成问题意味着我必须保存在一个我不想的地方。知道我为什么会收到错误消息吗?

So saving the context in between the two fetches avoids the crash, but poses a problem as it means I have to save in a place I would rather not. Any idea why I am getting the error?

推荐答案

目前尚不清楚为什么永远会起作用,因为您正在将数值与 compareSelector 进行比较,您将其定义为 NSString 上的方法。错误消息恰好描述了这一点-您正尝试使用数字不存在的方法比较两个数字。

It's unclear why this would ever work, because you're comparing numeric values with compareSelector, which you define to be a method on NSString. The error message describes this exactly-- you're trying to compare two numbers using a method that doesn't exist for numbers.

使用排序描述符时,选择器比较器版本的构造函数仅在您不希望<$的值隐含公共排序的情况下才需要c $ c>升序。对于数字值,如果只希望按值对它们进行排序,则不需要。您可以简单地使用

When using sort descriptors, the selector and comparator versions of the constructors are only necessary if you don't want the common sorting implied by the value of ascending. In the case of numeric values, if you simply want them sorted by value, you don't need either. You can simply use something like

NSSortDescriptor(key: #keyPath(Club.leaguePoints),
                      ascending: false)

这篇关于除非我先调用saveContext,否则无法识别的选择器会在核心数据中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆