SLN
SLN

Reputation: 5082

The required encoding function doesn't shown in a working code

serialization and deserialization is done by the two method defined in the NSCoding protocol as follow

encodeWithCoder(_ aCoder: NSCoder) {
    // Serialize your object here
}

init(coder aDecoder: NSCoder) {
    // Deserialize your object here
}

In my own ViewController (inherited from UITableViewController), I have a Array which contain my own object named Item and I do implemented the init(coder aDecoder: NSCoder) initial function. The Item is defined as follow

class Item: NSObject, NSCoding {
    var text = ""
    var checked = false

    func toggleChecked() {
            checked = !checked
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.text, forKey: "SLAText")
        aCoder.encode(self.checked, forKey: "SLAChecked")
    }

    required init?(coder aDecoder: NSCoder) {
        self.text = aDecoder.decodeObject(forKey: "SLAText") as! String
        self.checked = aDecoder.decodeBool(forKey: "SLAChecked")
        super.init()
    }

    override init() {
        super.init()
    }
}

Instead implement the function encode(with: NSCoder) I defined my own serialization function named saveItems()

 func saveItems() {
        let data = NSMutableData()
        let archiver = NSKeyedArchiver(forWritingWith: data)

        archiver.encode(items, forKey: "ItemLists") //items is a array of type [Item]
        archiver.finishEncoding()

        data.write(to: dataFilePath(), atomically: true)      
    }

Question

Why the code is working with out implement the required NSCoding function? The code is simplified from a example of the book I'm studying, I didn't find the encodeWithCoder(_ aCoder: NSCoder) function at all. Isn't the required means you have to implemented it?

Thanks for your time and help

Upvotes: 0

Views: 93

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59506

Why the code is working with out implement the required NSCoding function?

This is not true.

NSCoding is a protocol

First of all NSCoding is a protocol, not a function. And in order to conform a type to NSCoding you need to implement a method and an initializer

public func encode(with aCoder: NSCoder)
public init?(coder aDecoder: NSCoder)

Why does your code work?

Let's look at what you are doing

archiver.encode(items, forKey: "ItemLists")

Here items is defined as [Item] which is and array of Item(s). And Array does conform to NSCoding. This can be easily tested by writing

let nums = [1, 2, 3]

if nums is NSCoding {
    print("Array does conform to NSCoding")
} else {
    print("Array does NOT conform to NSCoding")
}

The result is

Array does conform to NSCoding

Conclusion

Of course to work properly the element inside of the array must be conform to NSCodable too. And since the generic type of your Array is Item (which you made conform to NSCodable) the mechanism does work properly.

Upvotes: 1

Related Questions