ios - 除非我先调用 saveContext,否则核心数据中无法识别的选择器崩溃

标签 ios swift core-data

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

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()

...一切正常。然而,如果我打电话...

workOutResults()
processUpdates()

...我在 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

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

最佳答案

不清楚为什么这会曾经起作用,因为您正在将数值与 compareSelector 进行比较,您将其定义为 NSString 上的方法>。错误消息对此进行了准确描述——您正在尝试使用数字不存在的方法来比较两个数字。

当使用排序描述符时,selectorcomparator 版本的构造函数只有在您不希望 的值隐含的公共(public)排序时才需要升序。对于数值,如果您只想按值对它们进行排序,则两者都不需要。你可以简单地使用类似的东西

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

关于ios - 除非我先调用 saveContext,否则核心数据中无法识别的选择器崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48310482/

相关文章:

cocoa - 在 Interface Builder 中使表格的显示依赖于另一个表格中的选择

ios - 使用模式弹出窗口将行插入到 tableView

swift - 在 Swift 3 中更新范围

ios - 队列和 Swift 3 问题

objective-c - NSPredicate 键路径在右侧

iphone - NSSortDescriptor 和多对多关系

ios - 自动布局和对齐约束

ios - 如何通过应用程序ID确定iOS上哪些应用程序是后台应用程序,哪些应用程序是前台应用程序

ios - 旋转后改变棋盘颜色

ios - 应用内购买 swift