Simple Swift class does not compile
Asked Answered
S

3

4

My simple class, ClassWithOneArray, produces this error:

Bitcast requires both operands to be pointer or neither %19 = bitcast i64 %18 to %objc_object*, !dbg !470 LLVM ERROR: Broken function found, compilation aborted! Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1

However, my class, ClassWithOneInt, does not. Why?

class ClassWithOneInt {
    var myInt = Int()
    init(myInt: Int) {
        self.myInt = Int()
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(myInt, forKey: "myInt")
    }
    init(coder aDecoder: NSCoder) {
        self.myInt = aDecoder.decodeObjectForKey("myInt") as Int
    }
}

class ClassWithOneArray {
    var myArray = String[]()
    init(myArray: String[]) {
        self.myArray = String[]()
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(myArray, forKey: "myArray")
    }
    init(coder aDecoder: NSCoder) {
        self.myArray = aDecoder.decodeObjectForKey("myArray") as String[]
    }
}
Stpeter answered 25/6, 2014 at 0:30 Comment(3)
This pretty clearly looks like a compiler bug, given that the compiler is crashing.Flagman
OK, thanks. I will submit a bug report.Stpeter
This seems to compile fine with the Beta 2 compiler.Kopple
K
3

As I point out in comments, your example seems to compile fine on beta 2, although it still won't work for a couple of reasons, for encoderWithCoder to be of any use, ClassWithOneArray needs to:

  1. declare conformance with NSCoding,
  2. implement NSCoding,
  3. inherit from NSObject or implement NSObjectProtocol, and,
  4. use a non-mangled name.

All told, that means:

@objc(ClassWithOneArray)
class ClassWithOneArray:NSObject, NSCoding {
    var myArray: String[]
    init(myArray: String[]) {
        self.myArray = myArray
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(myArray, forKey: "myArray")
    }
    init(coder aDecoder: NSCoder) {
        self.myArray = aDecoder.decodeObjectForKey("myArray") as String[]
    }
}

Also it seems as if the simple methods of testing archiving aren't available in the playground, probably because the classes don't get properly registered.

let foo = ClassWithOneArray(myArray:["A"])

let data = NSKeyedArchiver.archivedDataWithRootObject(foo)

let unarchiver = NSKeyedUnarchiver(forReadingWithData:data)
unarchiver.setClass(ClassWithOneArray.self, forClassName: "ClassWithOneArray")
let bar = unarchiver.decodeObjectForKey("root") as ClassWithOneArray
Kopple answered 25/6, 2014 at 5:44 Comment(2)
Note that @rjsamson is also correct in his observation that you're declaring myArray incorrectly, his usage of var myArray: String[] would be better.Kopple
Thanks. That helps me on multiple levels.Stpeter
R
0

It looks like your syntax is a bit off for what you're trying to accomplish - something like this should work:

class ClassWithOneInt {
    var myInt: Int
    init(myInt: Int) {
        self.myInt = myInt
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(myInt, forKey: "myInt")
    }
    init(coder aDecoder: NSCoder) {
        self.myInt = aDecoder.decodeObjectForKey("myInt") as Int
    }
}

class ClassWithOneArray {
    var myArray: String[]
    init(myArray: String[]) {
        self.myArray = myArray
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(myArray, forKey: "myArray")
    }
    init(coder aDecoder: NSCoder) {
        self.myArray = aDecoder.decodeObjectForKey("myArray") as String[]
    }
}
Repay answered 25/6, 2014 at 1:32 Comment(1)
Thanks, but I still get the same error on Build, which only goes away when I comment out ClassWithOneArray, just like with my codeStpeter
C
0

In my experience simply declaring the Protocol "NSCoding" to your class should do the trick. Hope this helps someone.

Claret answered 1/8, 2014 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.