Search code examples
iosxcodeswiftsegmentation-faultprotocol-extension

Protocol extensions are not in effect (Swift)


As of the time of writing this question, I am using Swift 2.1 and Xcode 7.2.1.

The code below (meant for encoding a struct) does not work and makes an Xcode playground crash without error. When in a project, it causes a segmentation fault during compilation.

protocol StructCoding {
    typealias structType

    func encode() -> NSData

    static func decode(data: NSData) -> Self
}

extension StructCoding {

    mutating func encode() -> NSData {
        return withUnsafePointer(&self) { p in
            NSData(bytes: p, length: sizeofValue(self))
        }
    }

    static func decode(data: NSData) -> structType {
        let pointer = UnsafeMutablePointer<structType>.alloc(sizeof(structType))
        data.getBytes(pointer, length: sizeof(structType))
        return pointer.move()
    }
}

struct testStruct: StructCoding {
    let a = "dsd"
    let b = "dad"
    typealias structType = testStruct
}

but these could work.

struct testStruct: StructCoding {
    let a = "dsd"
    let b = "dad"

    mutating func encode() -> NSData {
        return withUnsafePointer(&self) { p in
            NSData(bytes: p, length: sizeofValue(self))
        }
    }

    static func decode(data: NSData) -> testStruct {
        let pointer = UnsafeMutablePointer<testStruct>.alloc(sizeof(testStruct))
        data.getBytes(pointer, length: sizeof(testStruct))
        return pointer.move()
    }

}

var s1 = testStruct()
let data = s1.encode()
let s2 = testStruct.decode(data)

Solution

  • Answer: The problem is that you are declaring encode as a non-mutating function, however implementing it as a mutating function (in both of the provided code).

    Change encode's declaration (in the protocol) from func encode() -> NSData to mutating func encode() -> NSData in order to match your needs.