2017-06-26 20 views
2

私はコインコレクションアプリを開発しています。最近、コアデータをアプリに統合し始めました。カスタムCoinCategoryオブジェクトを格納するコアデータデータベースがあり、各CoinCategoryオブジェクトにはCoinオブジェクトの配列があります。この方法では、私のアプリはカテゴリの点ですべてを保存します。コアデータ変更処理時のエラー

私はコアデータを統合すると、私はエラーなしで私の最初のカテゴリを追加し、何の問題もなくそれを削除しますが、私は2番目のコインカテゴリに追加したときに、私は次のエラーを体験することができます

2017-06-26 09:55:37.218 CoinCollection[18889:12839563] -[CoinCollection.CoinCategory compare:]: unrecognized selector sent to instance 0x608000236cc0 2017-06-26 09:55:37.219215-0400 CoinCollection[18889:12839563] [error] error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[CoinCollection.CoinCategory compare:]: unrecognized selector sent to instance 0x608000236cc0 with userInfo (null) CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[CoinCollection.CoinCategory compare:]: unrecognized selector sent to instance 0x608000236cc0 with userInfo (null)

誰でもこの問題を解決する方法を教えてください。どうもありがとうございました!

私は自分のviewcontrollerとコアデータを実行しているアプリケーションデリゲートのために私のコードを添付しています。

AppDelegate.swift 
    // We customize the app, system-wide 
    import UIKit 
    import CoreData 


    @UIApplicationMain 
    class AppDelegate: UIResponder, UIApplicationDelegate { 



var window: UIWindow? 



// MARK: - Core Data stack 
lazy var persistentContainer: NSPersistentContainer = { 
    let container = NSPersistentContainer(name: "CoinCollection") 
    container.loadPersistentStores(completionHandler: { (storeDescription, 
     error) in 
     if let error = error as NSError? { 
      fatalError("Unresolved error \(error), \(error.userInfo)") 
     } 
    }) 
    return container 
}() 
// MARK: - Core Data Saving support 
func saveContext() 
{ 
    let context = persistentContainer.viewContext 

    if context.hasChanges 
    { 
     do 
     { 
      try context.save() 
     } 
     catch 
     { 
      // Replace this implementation with code to handle the error appropriately. 
      // fatalError() causes the application to generate a crash log and terminate. 
      //You should not use this function in a shipping application, although it may be useful during development. 
      let nserror = error as NSError 
      fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 
     } 
    } 
} 
    } 

次にビューコントローラ用です。このメソッドを呼び出すサブビューコントローラからCoinオブジェクトを取得し、Coinオブジェクトが既存のカテゴリに適合するかどうかを判断することに注意してください。そうでない場合は、新しいコインを追加します。

// Controls the table view controller showing the general coins (one per each category) 
    import UIKit 
    import CoreData 

    class CoinTableViewController: UITableViewController, NSFetchedResultsControllerDelegate { 


//this is an array of all the coins in the collection 
//each row of this two-dimensional array represents a new category 
var coinsByCategory: [CoinCategoryMO] = [] 
var fetchResultController: NSFetchedResultsController<CoinCategoryMO>! 


//other attributes.... 





//////////////////////////////////////////////////////////////////////// 
override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    ////////////////////////////////////////////////////////////////////////////////// 

    //we now fetch the data 
    let fetchRequest : NSFetchRequest<CoinCategoryMO> = CoinCategoryMO.fetchRequest() 

    if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) 
    { 
     let context = appDelegate.persistentContainer.viewContext 

     let sortDescriptor = NSSortDescriptor(key: "coinCategory", ascending: true) 
     fetchRequest.sortDescriptors = [sortDescriptor] 

     fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
     fetchResultController.delegate = self 

     do 
     { 
      try fetchResultController.performFetch() 
      if let fetchedObjects = fetchResultController.fetchedObjects 
      { 
       self.coinsByCategory = fetchedObjects 
      } 
     } 
     catch 
     { 
      print(error) 
     } 
    } 

    //configure even more....  
} 



// MARK: - Table view data soure 

func deleteCoinCategory(rowPath: IndexPath) 
{ 
    if 0 <= rowPath.row && rowPath.row < self.coinsByCategory.count 
    { 
     //we have just tested that the rowPath index is valid 
     if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) 
     { 
      let context = appDelegate.persistentContainer.viewContext 
      let coinCategoryToDelete = self.fetchResultController.object(at: rowPath) 
      context.delete(coinCategoryToDelete) 

      appDelegate.saveContext() 
     } 
    } 
} 

func deleteCoin(c: Coin, indexOfSelectedCategory: IndexPath) -> Bool 
{ 
    //we have a coin that we want to delete from this viewcontroller 
    //and the data contained in it. 
    // 
    //the parameter indexOfSelectedCategory refers to the IndexPath of the 
    //row in the TableView contained in THIS viewcontroller whose category 
    //of coins we are modifying in this method 
    // 
    //Return value: a boolean that indicates whether a single coin has 
    //been deleted - meaning that the user should return to the parentviewcontroller 
    if 0 < indexOfSelectedCategory.row && indexOfSelectedCategory.row < self.coinsByCategory.count && self.coinsByCategory[indexOfSelectedCategory.row].coinCategory?.hasCoin(c: c) == true 
    { 
     //the index is valid as it refers to a category in the coinsByCategory array 
     //and the examined category has the coin in question 
     if self.coinsByCategory[indexOfSelectedCategory.row].coinCategory?.count == 1 
     { 
      //the coin "c" that we are going to delete is the only coin in the entire category 
      self.deleteCoinCategory(rowPath: indexOfSelectedCategory) 

      return true 
     } 
     else 
     { 
      //more than one coin in the category 
      self.coinsByCategory[indexOfSelectedCategory.row].coinCategory?.removeCoin(c: c) 

      //we save the changes in the database... 
      if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) 
      { 
       appDelegate.saveContext() 
      } 

      return false 
     } 
    } 

    return false 
} 

func addCoin(coinToAdd: Coin) 
{ 
    //we check over each category to see if the coin can be added 
    for category in self.coinsByCategory 
    { 
     if category.coinCategory?.coinFitsCategory(aCoin: coinToAdd) == true 
     { 
      //we can add the coin to the category 
      category.coinCategory?.addCoin(newCoin: coinToAdd) 

      if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) 
      { 
       //we save changes to the database 
       appDelegate.saveContext() 

       //we are DONE with this function 
       return 
      } 
     } 
    } 

    //since the coinToAdd does not fall in the existing categories, we create a new one 
    if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) 
    { 
     let newCategory = CoinCategoryMO(context: appDelegate.persistentContainer.viewContext) 


     newCategory.coinCategory = CoinCategory(coins: [coinToAdd], categoryType: CoinCategory.CategoryTypes.COUNTRY_VALUE_AND_CURRENCY) 


     print("Saving data to context ...") 
     appDelegate.saveContext() 
    } 
} 



//delegate methods control the core data database 
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
{ 
    tableView.beginUpdates() 
} 

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) 
{ 
    switch type 
    { 
    case .insert : 
     if let newIndexPath = newIndexPath 
     { 
      tableView.insertRows(at: [newIndexPath], with: .fade) 
     } 

    case .delete: 
     if let indexPath = indexPath 
     { 
      tableView.deleteRows(at: [indexPath], with: .fade) 
     } 

    case .update: 
     if let indexPath = indexPath 
     { 
      tableView.reloadRows(at: [indexPath], with: .fade) 
     } 

    default: 
     tableView.reloadData() 
    } 

    if let fetchedObjects = controller.fetchedObjects 
    { 
     self.coinsByCategory = fetchedObjects as! [CoinCategoryMO] 
    } 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
{ 
    tableView.endUpdates() 
    } 

あなたのご意見やご感想をお待ちしております。

EDIT:CoinCategoryクラスの

マイコード:

// This class is supposed to represent a category of coin objects in CoreData 

import Foundation 
import CoreData 

    public class CoinCategory: NSObject, NSCoding 
    { 
     //These are the various types of categories that a user can create out of their coin collection 
     enum CategoryTypes : NSString 
     { 
      case COUNTRY_VALUE_AND_CURRENCY = //... 
      case COUNTRY = //... 
      case YEAR = //... 
      case CURRENCY = //... 
      case NO_CATEGORY = //... 
     } 

//this struct is used to encode data in Key-Value pairs per the NSCoding protocol 
struct Keys 
{ 
    static let Current_Category_Type = "current_category_type" 
    static let Coins_In_Category = "coins_in_category" 
} 

//this is the collection of the coins in the category 
var coinsInCategory: [Coin] = [] //initially we have no coins in the collection 
var currentCategoryType : CategoryTypes.RawValue = "" 

public var count : NSNumber 
{ 
    get 
    { 
     //..number of coins in category 
    } 
} 

public var array : [Coin] 
{ 
    get 
    { 
     //read-only copy of the Coins array.. 
    } 
} 

public required init?(coder aDecoder: NSCoder) 
{ 
    //we decode this object's information 
    if let categoryTypeObject = aDecoder.decodeObject(forKey: Keys.Current_Category_Type) as? CategoryTypes.RawValue 
    { 
     self.currentCategoryType = categoryTypeObject 
    } 

    if let coinsInCategoryArrayObject = aDecoder.decodeObject(forKey: Keys.Coins_In_Category) as? [Coin] 
    { 
     self.coinsInCategory = coinsInCategoryArrayObject 
    } 
} 

public func encode(with aCoder: NSCoder) 
{ 
    //we encode this object's information 
    aCoder.encode(currentCategoryType, forKey: Keys.Current_Category_Type) 
    aCoder.encode(self.coinsInCategory, forKey: Keys.Coins_In_Category) 
} 

override init() 
{ 
    super.init() 
    self.currentCategoryType = CategoryTypes.COUNTRY_VALUE_AND_CURRENCY.rawValue 
    self.coinsInCategory = [] 
} 

convenience init(coins: [Coin], categoryType: CategoryTypes.RawValue) 
{ 
    self.init() 
    self.coinsInCategory = coins 

    if isACategoryType(categoryType: categoryType) == true 
    { 
     self.currentCategoryType = categoryType 
    } 
    else 
    { 
     self.currentCategoryType = CategoryTypes.NO_CATEGORY.rawValue 
    } 
} 

func isACategoryType(categoryType: NSString) -> Bool 
{ 
    switch categoryType 
    { 
    case CategoryTypes.COUNTRY_VALUE_AND_CURRENCY.rawValue: 
     return true 
    case CategoryTypes.COUNTRY.rawValue: 
     return true 
    case CategoryTypes.YEAR.rawValue: 
     return true 
    case CategoryTypes.CURRENCY.rawValue: 
     return true 
    default: 
     return false 
    } 
} 

func addCoin(newCoin: Coin) 
{ 
    //we are adding a new Coin object to this category 
    //if it falls into the category's type 
    if self.coinFitsCategory(aCoin: newCoin) == true 
    { 
     self.coinsInCategory.append(newCoin) 
    } 
} 

func coinFitsCategory(aCoin: Coin) -> Bool 
{ 
    //this function tests if aCoin fits into the category type 
    //but that all varies depending on which category the coin is 
    if self.coinsInCategory.count == 0 
    { 
     //this category is currently empty, so any addition goes! 
     return true 
    } 

    //otherwise, this category is not empty... so we are now going to 
    //examine the situation more critically 
    let testCoin = self.coinsInCategory[0] 


    switch self.currentCategoryType 
    { 
     case CategoryTypes.COUNTRY_VALUE_AND_CURRENCY.rawValue: 
      return (testCoin.getCountry().lowercased == aCoin.getCountry().lowercased) && (testCoin.getValue() == aCoin.getValue()) && (testCoin.getDenomination().lowercased == aCoin.getDenomination().lowercased) 

    case CategoryTypes.COUNTRY.rawValue: 
     return testCoin.getCountry().lowercased == aCoin.getCountry().lowercased 

    case CategoryTypes.CURRENCY.rawValue: 
     return testCoin.getDenomination().lowercased == aCoin.getDenomination().lowercased 

    case CategoryTypes.YEAR.rawValue: 
     return testCoin.getYear() == aCoin.getYear() 

    default: 
     return false 
    } 
} 

func getIndexOfCoinInCollection(coin: Coin) -> Int 
{ 
    //we are going to return -1 if the coin does not exist in the collection 
    //and are going to return the index otherwise if yes 
    for i in 0..<self.coinsInCategory.count 
    { 
     if coinsInCategory[i] == coin 
     { 
      return i 
     } 
    } 

    //have not found anything 
    return -1 
} 

func removeCoin(at: Int) 
{ 
    //we remove the coin at the index if it is in a valid range of the coinInCategory array 
    if isValidArrayIndex(index: at) 
    { 
     self.coinsInCategory.remove(at: at) 
    } 
} 

func getCoin(at: Int) -> Coin? 
{ 
    //we return nil if there is an issue in accessing the coin 
    if isValidArrayIndex(index: at) 
    { 
     return self.coinsInCategory[at] 
    } 
    else 
    { 
     return nil 
    } 
} 

func assignCoin(at: Int,c: Coin) 
{ 
    if isValidArrayIndex(index: at) 
    { 
     self.coinsInCategory[at].assign(right: c) 
    } 
} 

func deleteAllCoins() 
{ 
    //we delete all the coin in this category 
    self.coinsInCategory.removeAll() 
} 

func removeCoin(c: Coin) 
{ 
    //we delete a coin from the category 
    for i in 0..<self.coinsInCategory.count 
    { 
     if self.coinsInCategory[i] == c 
     { 
      //the coin at index "i" is equal to the coin "c" that we want to delete from the category 
      self.coinsInCategory.remove(at: i) 
      return 
     } 
    } 
} 

func hasCoin(c: Coin) -> Bool 
{ 
    return getIndexOfCoinInCollection(coin: c) != -1 
} 

func swapValuesWithAnotherCategory(other: CoinCategory) 
{ 
    swap(&self.currentCategoryType, &other.currentCategoryType) 
    swap(&self.coinsInCategory,&other.coinsInCategory) 
} 

func swapCoins(indexOne: Int, indexTwo: Int) 
{ 
    if isValidArrayIndex(index: indexOne) && isValidArrayIndex(index: indexTwo) 
    { 
     swap(&self.coinsInCategory[indexOne],&self.coinsInCategory[indexTwo]) 
    } 
} 

private func isValidArrayIndex(index: Int) -> Bool 
{ 
    return (0 <= index && index < coinsInCategory.count) 
}  
    } 

そしてコインカテゴリクラス: //これはプロジェクト

import UIKit 
    import CoreData 

    enum TimePeriods: String 
    { 
     //this enumeration represents the different time periods that a 
     //coin was minted in, for the sake of this programn 
     case BCE = "BCE" 
     case CE = "CE" 
    } 

    public class Coin : NSObject, NSCoding 
    { 
     //this struct represents all the keys used in encoding and decoding this object 
     struct Keys 
     { 
      static let Country = "country" 
      static let Mint = "mint" 
      static let Year = "year" 
      static let Currency = "currency" 
      static let Value = "value" 
      static let Grade = "grade" 
      static let Comments = "comments" 
      static let NumInstances = "numberInstances" 
      static let Description = "description" 
      static let Obverse = "obverse" 
      static let Reverse = "reverse" 
     } 
//this represents a coin in the table view 
static let GRADING_LOWER_LIMIT: NSNumber = 1 
static let GRADING_UPPER_LIMIT: NSNumber = 70 

//this represents the default strings returned if a field does not have the needed information 
static let DEFAULT_DESCRIPTIVE_NAME: NSString = "(Description?)" 
static let DEFAULT_COMMENTS: NSString = "(Comments?)" 
static let DEFAULT_DENOMINATION: NSString = "(Denomination?)" 
static let DEFAULT_MINT: NSString = "(Mint?)" 
static let DEFAULT_COUNTRY: NSString = "(Country?)" 
static let DEFAULT_YEAR: NSString = "(Year?)" 
static let DEFAULT_GRADE: NSString = "(Grade?)" 
static let DEFAULT_VALUE_AND_DENOMINATION: NSString = "(Value?) (Currency?)" 

static let OBVERSE_IMAGE_STRING : NSString = "Obverse" 
static let REVERSE_IMAGE_STRING : NSString = "Reverse" 

static private let BULLET = "➣ "   //represents the kind of bullet to be used to build a complete summary of the coin 

//declare members with setters and getters 
private var country: NSString = ""  //what country/empire/etc. used in? 
private var mint: NSString = ""   //where minted? EX: US Mint, St. Petersburg 
private var year: NSNumber? = nil    //what year minted? per gregorian calendar 
            //the year can be negative to represent the BCE period 
            //positive to represent the CE periods 
private var typeCurrency: NSString = ""  //what is the unit of value? EX: Cents, dollars, centavos, etc 
private var theValue: NSNumber = 0   //how many? EX: how many dollars, cents, centavos, etc.? 


//additional information about the coin 
private var grade: NSNumber?   //on the american grading scale for coins. 1-70 
private var comments: NSString = ""  //extra comments stored by the user for himself 


private var numberOfInstances: NSNumber = 0 //number of coins exactly like this. EX: 1,2,3,4...etc? For each instance, it must be >= 1. 

//This describes the type of the coin 
//EX: Walking Liberty Quarter, Barber Quarter, Standing Liberty Quarter... etc 
private var descriptiveName: NSString = "" 

private var obverseImage: UIImage? = nil 
private var reverseImage: UIImage? = nil 


public var valueAndDenomination: NSString 
{ 
    get 
    { 
     //need to check four cases 
     //case 1: we have the right values for value and denomination 
     //case 2: we do not have a value but do have denomination 
     //case 3: we have a value but do not have denomination 
     //case 4: we do not have both 
     // 
     //the reason why we consider 0 to be an empty value is because a coin that was worth 
     //nothing would not have been minted in the first place!!! 
     if (self.theValue != 0 && self.typeCurrency != "") 
     { 
      //have value and denomination 
      return "\(self.theValue) \(self.typeCurrency)" as NSString //like "20 Cents" 
     } 

     else if (self.theValue == 0 && self.typeCurrency != "") 
     { 
      //do not have value, but have denomination 
      return "(Value?) \(self.typeCurrency)" as NSString 
     } 

     else if (self.theValue != 0 && self.typeCurrency == "") 
     { 
      //we have value, but do not have denomination 
      return "\(self.theValue) (Currency?)" as NSString 
     } 

     else 
     { 
      //we do not have both 
      return Coin.DEFAULT_VALUE_AND_DENOMINATION as NSString 
     } 

    } 
} 

public required init?(coder aDecoder: NSCoder) 
{ 
    //we decode this object's information 
    if let countryObject = aDecoder.decodeObject(forKey: Keys.Country) as? NSString 
    { 
     self.country = countryObject 
    } 

    if let mintObject = aDecoder.decodeObject(forKey: Keys.Country) as? NSString 
    { 
     self.mint = mintObject 
    } 

    if let yearObject = aDecoder.decodeObject(forKey: Keys.Year) as? NSNumber 
    { 
     self.year = yearObject 
    } 

    if let currencyObject = aDecoder.decodeObject(forKey: Keys.Currency) as? NSString 
    { 
     self.typeCurrency = currencyObject 
    } 

    if let valueObject = aDecoder.decodeObject(forKey: Keys.Value) as? NSNumber 
    { 
     self.theValue = valueObject 
    } 

    if let gradeObject = aDecoder.decodeObject(forKey: Keys.Grade) as? NSNumber 
    { 
     self.grade = gradeObject 
    } 

    if let commentObject = aDecoder.decodeObject(forKey: Keys.Comments) as? NSString 
    { 
     self.comments = commentObject 
    } 

    if let numInstancesObject = aDecoder.decodeObject(forKey: Keys.NumInstances) as? NSNumber 
    { 
     self.numberOfInstances = numInstancesObject 
    } 

    if let descriptiveNameObject = aDecoder.decodeObject(forKey: Keys.Description) as? NSString 
    { 
     self.descriptiveName = descriptiveNameObject 
    } 

    if let obverseImageObject = aDecoder.decodeObject(forKey: Keys.Obverse) as? UIImage 
    { 
     self.obverseImage = obverseImageObject 
    } 

    if let reverseImageObject = aDecoder.decodeObject(forKey: Keys.Reverse) as? UIImage 
    { 
     self.reverseImage = reverseImageObject 
    } 
} 
override init() 
{ 
    //default initializer 
    super.init() 

    self.country = "" 
    self.mint = "" 
    self.year = nil 
    self.typeCurrency = "" 
    self.theValue = 0 
    self.comments = "" 
    self.numberOfInstances = 1 
    self.descriptiveName = "" 
    self.obverseImage = nil 
    self.reverseImage = nil 
} 

init(country: NSString,year: Int?,typeCurrency: NSString, theValue: NSNumber,mint: NSString,grade: Int?,numInstances: NSNumber = 1,description: NSString, comments: NSString) 
{ 
    super.init() 
    self.country = country 
    self.mint = mint 
    self.year = year! as NSNumber 
    self.typeCurrency = typeCurrency 
    self.theValue = theValue 
    self.comments = comments 
    self.numberOfInstances = numInstances 
    self.descriptiveName = description 

    self.obverseImage = nil 
    self.reverseImage = nil 
} 

init(country: NSString,year: NSNumber?,typeCurrency: NSString, theValue: NSNumber,mint: NSString,grade: NSNumber?,numInstances: NSNumber = 1,description: NSString, comments: NSString,obverseImage: UIImage, reverseImage: UIImage) 
{ 
    super.init() 
    self.country = country 
    self.mint = mint 
    self.year = year 
    self.typeCurrency = typeCurrency 
    self.theValue = theValue 
    self.comments = comments 
    self.numberOfInstances = numInstances 
    self.descriptiveName = description 
} 

public func encode(with aCoder: NSCoder) 
{ 
    //we encode the coin's information 
    aCoder.encode(self.country, forKey: Keys.Country) 
    aCoder.encode(self.mint, forKey: Keys.Mint) 
    aCoder.encode(self.year, forKey: Keys.Year) 
    aCoder.encode(self.typeCurrency, forKey: Keys.Currency) 
    aCoder.encode(self.theValue, forKey: Keys.Value) 
    aCoder.encode(self.grade, forKey: Keys.Grade) 
    aCoder.encode(self.comments, forKey: Keys.Comments) 
    aCoder.encode(self.numberOfInstances, forKey: Keys.NumInstances) 
    aCoder.encode(self.descriptiveName, forKey: Keys.Description) 
    aCoder.encode(self.obverseImage, forKey: Keys.Obverse) 
    aCoder.encode(self.reverseImage, forKey: Keys.Reverse) 
} 



//setter and getter functions for class members... 


func getCompleteSummary() -> NSString 
{ 
    //returns a bulleted list that represents the coin 
    //and it describes every single detail... 
} 

func getIncompleteSummary() -> String 
{ 
     //returns a bulleted list string that represents the coin 
     //and it describes every single detail...  
} 

///////////////////////////////////////////////////////////////////////////////// 

func ofSameType(rhs: Coin) -> Bool 
{ 
    return (self.getCountry().lowercased == rhs.getCountry().lowercased) && (self.getValue() == rhs.getValue()) && (self.getDenomination().lowercased == rhs.getDenomination().lowercased) 
} 

public static func==(lhs: Coin, rhs: Coin) -> Bool 
{ 
    //we compare two coin objects for equality in ALL Categories 
    return lhs.country.lowercased == rhs.country.lowercased && 
      lhs.theValue == rhs.theValue && 
      lhs.typeCurrency.lowercased == rhs.typeCurrency.lowercased && 
      lhs.mint.lowercased == rhs.mint.lowercased && 
      lhs.year == rhs.year && 
      lhs.grade == rhs.grade && 
      lhs.comments == rhs.comments && 
      lhs.numberOfInstances == rhs.numberOfInstances && 
      lhs.descriptiveName == rhs.descriptiveName && 
      lhs.obverseImage == rhs.obverseImage && 
      lhs.reverseImage == rhs.reverseImage 
} 

func assign(right: Coin) 
{ 
    //we implement this instead of overloading the assignment "=" operator 
    //as it is not possible to overload the "=" operator 
    //we assign the right-hand-coin's field values 
    //to the left-hand coin's side 
    self.country = right.country 
    self.theValue = right.theValue 
    self.typeCurrency = right.typeCurrency 
    self.mint = right.mint 
    self.year = right.year 
    self.grade = right.grade 
    self.comments = right.comments 
    self.numberOfInstances = right.numberOfInstances 
    self.descriptiveName = right.descriptiveName 
    self.obverseImage = right.obverseImage 
    self.reverseImage = right.reverseImage 
} 

    } 
のためのクラスコインのクラス定義を提供
+0

サンプルコードには、コードを削除してコメントを置き換えて、フォーラムの長さを特定の長さの文字に縮小する機能があることに注意してください投稿します。 – PhysNerd

答えて

0

CoinCategoryクラスがcompare:メソッドを実装していないという問題があるようです:

[CoinCollection.CoinCategory compare:]: unrecognized selector sent to instance 0x608000236cc0

私の推測では、FRCはあなたのFRCはcoinCategory使用してソートされているので(正しい順序でそれらを取得するために、第1 CoinCategoryMOcoinCategory属性に二CoinCategoryMOcoinCategory属性を比較しようとしていることです属性)。

CoinCategoryクラスに対してcompare:メソッドを実装する必要があるという直接的な回答です。しかし、私はこれがあなたのアプローチを変える必要があることの指標に過ぎないと思います。カスタムオブジェクト(またはそのコレクション)である属性を持つエンティティを持つのではなく、多対多の関係を持つ複数のエンティティ(たとえば、CoinMOエンティティ、CoinCategoryMOエンティティ、CoinCategoryTypeMOエンティティなど)を持つ必要があります。独自のオブジェクト(​​とCoinCategory)のコードを表示すると、CoreDataでモデル化する方法をアドバイスする方が簡単になります。

+0

お返事ありがとうございます。大変感謝しています。 ** compare **メソッドはどのように実装しますか?これは初めてのコアデータの作業で、私がグーグルで見つけたものはすべて私を挫折させました。今、私はこの投稿を編集し、CoinとCoinCategoryのクラスを投稿します。 – PhysNerd

+0

私の中核的なデータ関係は以下の通りです: "CoinCategoryMO"と呼ばれる生成されたクラス。クラスタイプCoinCategoryの "transformable"型の "coinCategory"エンティティを持ちます。しかし、私の主な目標は、この問題を解決して、アプリケーションのアプローチを完全に消して新たに開始することではありません。お手伝いありがとう! – PhysNerd

+0

@PhysNerd ** compare **の実装を試したい場合は、CoinCategoryクラスにcompareメソッドを追加する必要があります。 CoinCategory型の単一の引数をとり、 'ComparisonResult'を返さなければなりません(ドキュメンテーション[here](https://developer.apple.com/documentation/foundation/comparisonresult)参照)。しかし、私はあなたがこれを過ぎてもさらに問題になるだろうと思う。 – pbasdf

関連する問題