【问题标题】:Unrecognized selector sent to class (singleton)无法识别的选择器发送到类(单例)
【发布时间】:2017-03-22 15:17:11
【问题描述】:

我发现了一些关于这个问题的相关主题,但我不明白那里提出的解决方案如何适用于单例类。

当我的应用启动时,我在applicationDidBecomeActive 中调用gamestate.shardInstance(),但每次都会立即崩溃并出现相同的错误:

2017-03-22 11:09:09.102 project-mars[46108:28079112] +[project_mars.gameState encodeWithCoder:]: unrecognized selector sent to class 0x103670e60 2017-03-22 11:09:09.107 project-mars[46108:28079112] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[project_mars.gameState encodeWithCoder:]: unrecognized selector sent to class 0x103670e60'

有人可以帮我理解这个错误到底发生了什么以及如何解决它吗?谢谢!

class gameState: NSObject, NSCoding {

var GameSettings:gameSettings   //Structure that stores all the game settings
var PlayerStats:gameStatistics     //Structure that stores all game stats
var GameBoard:gameBoard        //Contains the information of the gameboard

private static var Instance: gameState = {
    let instance = gameState.loadgameState()
    //Closure for configuration
    return instance!
}()

private override init(){
    self.GameSettings = gameSettings()
    self.PlayerStats = gameStatistics()
    self.GameBoard = gameBoard()
    super.init()
}

class func sharedInstance() -> gameState{
    return gameState.Instance
}

required init?(coder aDecoder: NSCoder) {
    self.GameSettings = (aDecoder.decodeObject(forKey: "GameSettings") as? gameSettings)!
    self.PlayerStats = (aDecoder.decodeObject(forKey: "PlayerStats") as? gameStatistics)!
    self.GameBoard = (aDecoder.decodeObject(forKey: "GameBoard") as? gameBoard)!
}
func encode(with aCoder: NSCoder) {
    aCoder.encode(gameState.sharedInstance().GameSettings, forKey: "GameSettings")
    aCoder.encode(gameState.sharedInstance().PlayerStats, forKey: "PlayerStats")
    aCoder.encode(gameState.sharedInstance().GameBoard, forKey: "GameBoard")
}
class func loadgameState() ->gameState? {
    let path = gameState.getFilePath()
    print("PATH: \(path) \n")
    if gameState.fileExistsAtPath(path: path){
        if let rawData = NSData(contentsOfFile: path) {
            /// do we get serialized data back from the attempted path?
            /// if so, unarchive it into an AnyObject, and then convert to a GameData object
            if(rawData.length != 0){
                if let data = NSKeyedUnarchiver.unarchiveObject(with: rawData as Data) as? gameState {
                    return data
                }
            }
        }
        return gameState()
    }else{
        return gameState()
    }
}

【问题讨论】:

  • 无意冒犯,但您的代码读起来很糟糕。命名约定(大写和小写)是相反的。
  • 感谢您的评论,我会说这是一种风格偏好,但每个人都有自己的偏好。如果您看不懂,请不要,我认为它不是很清楚。
  • 如果您的风格偏好与您正在与之交互的框架完全相反,并且还会使 SO 语法高亮显示所有内容颜色错误,那么它会使您的代码难以阅读。
  • gameState.loadgameState() 方法在哪里?正如其他人已经提到的那样——这个静态方法通常应该命名为GameState.loadGameState()。此外,您应该研究一种更 Swifty 的单例模式 static let sharedInstance = gameState() 就是您所需要的
  • 我同意 Vadian 的观点,该代码阅读起来非常混乱。我正在查看对静态方法的调用,并本能地认为它们是实例方法,它们做的事情非常不同。

标签: ios swift3 state-restoration


【解决方案1】:

我认为您应该能够使用本地实例,而无需在这里调用单例。你已经在单例实例中了

func encode(with aCoder: NSCoder) {
    aCoder.encode(gameState.GameSettings, forKey: "GameSettings")
    aCoder.encode(gameState.PlayerStats, forKey: "PlayerStats")
    aCoder.encode(gameState.GameBoard, forKey: "GameBoard")
}

请分享 gameState.loadgameState() 静态方法 - 我猜那里正在发生其他事情。

【讨论】:

    猜你喜欢
    • 2013-03-03
    • 1970-01-01
    • 2019-08-28
    • 2012-07-24
    相关资源
    最近更新 更多