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

时间:2018-01-17 21:43:31

标签: 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

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

1 个答案:

答案 0 :(得分:1)

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

使用排序描述符时,只有在您不希望comparator的值隐含的公共排序时,才需要ascendingNSSortDescriptor(key: #keyPath(Club.leaguePoints), ascending: false) 版本的构造函数。对于数值,如果您只是希望它们按值排序,则您也不需要。你可以简单地使用像

这样的东西
.then(response => {
    console.log(response);
    pngQuant.pngQuant(testObj['pngquant']); 
}, err =>console.log(err))
// then upload images
.then(response => {
  console.log(response);
}, err => console.log(err));