Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在UserDefault上使用NSKeyedArchiver时重置属性_Ios_Swift_Sprite Kit_Nskeyedarchiver_Userdefaults - Fatal编程技术网

Ios 在UserDefault上使用NSKeyedArchiver时重置属性

Ios 在UserDefault上使用NSKeyedArchiver时重置属性,ios,swift,sprite-kit,nskeyedarchiver,userdefaults,Ios,Swift,Sprite Kit,Nskeyedarchiver,Userdefaults,我有一个SKSpriteNode对象数组,我想将其持久化为UserDefaults。在下面的代码()中,我使用NSKeyedUnarchiver将数组编码为数据,然后将其设置为默认值。但是当我取消归档数据时,对象的engineSize属性被重置为默认值0 Car.swift import SpriteKit class Car: SKSpriteNode { var engineSize: Int = 0 init() { super.init(texture

我有一个
SKSpriteNode
对象数组,我想将其持久化为
UserDefaults
。在下面的代码()中,我使用
NSKeyedUnarchiver
将数组编码为数据,然后将其设置为默认值。但是当我取消归档数据时,对象的
engineSize
属性被重置为默认值0

Car.swift

import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0

    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()

    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }

        // Save to defaults
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")

        // Restore from defaults
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0
    
    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    required init(coder aDecoder: NSCoder) {
        engineSize = aDecoder.decodeInteger(forKey: "engineSize")
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    override func encode(with aCoder: NSCoder) {
        aCoder.encode(engineSize, forKey: "engineSize")
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()
    
    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }
        
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")
        
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
游戏场景。swift

import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0

    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()

    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }

        // Save to defaults
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")

        // Restore from defaults
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0
    
    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    required init(coder aDecoder: NSCoder) {
        engineSize = aDecoder.decodeInteger(forKey: "engineSize")
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    override func encode(with aCoder: NSCoder) {
        aCoder.encode(engineSize, forKey: "engineSize")
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()
    
    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }
        
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")
        
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
然而,这似乎不起作用<代码>游戏场景仍在将
引擎大小
打印为0。我是否实现了编码器/解码器错误?当属性从默认值还原时,如何防止将
引擎化
属性重置为0

更新

这是我更新的
Car
课程,我正试图让它与rmaddy的建议一起工作:

import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0

    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        if let engineSize = decoder.decodeObject(forKey: "engineSize") as? Int {
            self.engineSize = engineSize
        }
    }

    func encodeWithCoder(coder : NSCoder) {
        super.encode(with: coder)
        coder.encode(self.engineSize, forKey: "engineSize")
    }
}

代码编译并运行,但保存为默认值时,
engineSize
属性仍被重置为0。

我成功地使其正常工作。以下是更新后的
游戏场景
汽车
代码文件,其中
NSCoding
已正确执行

Car.swift

import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0

    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()

    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }

        // Save to defaults
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")

        // Restore from defaults
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0
    
    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    required init(coder aDecoder: NSCoder) {
        engineSize = aDecoder.decodeInteger(forKey: "engineSize")
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    override func encode(with aCoder: NSCoder) {
        aCoder.encode(engineSize, forKey: "engineSize")
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()
    
    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }
        
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")
        
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
游戏场景。swift

import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0

    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()

    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }

        // Save to defaults
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")

        // Restore from defaults
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}
import SpriteKit

class Car: SKSpriteNode {
    var engineSize: Int = 0
    
    init() {
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    required init(coder aDecoder: NSCoder) {
        engineSize = aDecoder.decodeInteger(forKey: "engineSize")
        super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
    }
    
    override func encode(with aCoder: NSCoder) {
        aCoder.encode(engineSize, forKey: "engineSize")
    }
}
import SpriteKit

class GameScene: SKScene {
    let defaults = UserDefaults.standard
    var carArray = [Car]()
    
    override func didMove(to view: SKView) {
        for _ in 1...3 {
            let car = Car()
            car.engineSize = 2000
            carArray.append(car)
        }
        
        defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")
        
        let arrayData = defaults.data(forKey: "carArrayKey")
        carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for c in carArray {
            print("Car's engine size is \(c.engineSize)")
        }
    }
}

你需要在
init(coder:)
encodeWithCoder(coder:)
方法中调用
super
。你还应该删除并重新安装你的应用程序,以确保用户默认值中没有以前尝试过的错误数据。我添加了
super.encode(with:coder)
好,但在
init(coder:)
编译器不喜欢调用
super.init(解码器)
。它抱怨说:
Car的便利初始值设定项必须委托(使用'self.init'),而不是链接到超类初始值设定项(使用'super.init')
init(coder:)
不应标记为便利初始值设定项。@rmaddy删除
convency
会产生错误。我更新了帖子以显示我正在尝试的代码。