Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use objective-c-runtime's object_getIvar & object_setIvar in swift?

Does anybody know why I get BAD_ACCESS on getting & setting of my iVars with the following code ?

class myClass: NSObject {
    var model = "Unspecified"

    override init() {
        super.init()

        var key: NSString = "model"
        var aClass : AnyClass? = self
        var ivar: Ivar = class_getInstanceVariable(aClass, key.UTF8String)

        // Set
        object_setIvar(aClass, ivar, "R56")

        // Get
        var value: AnyObject = object_getIvar(aClass, ivar)
    }

}

myClass()
like image 424
Tycho Pandelaar Avatar asked Nov 11 '22 02:11

Tycho Pandelaar


1 Answers

You get a bad access because Swift classes do not have traditional iVars anymore (try to grab a Swift class' iVar layout and see for yourself). But Swift classes are also Objective-C objects to the runtime, and there don't appear to be any paths excluding Swift classes in it.

What winds up happening is the runtime hands you a bogus iVar that it truly thinks points to a proper offset in the class definition (probably 0 or thereabouts because it doesn't exist). When you try to get said iVar, the runtime literally derefs you some of the object's bytes and tries to wrap it back up in an Objective-C pointer. Often this data has the tagged bit set unintentionally, and so often maps to tagged classes (in my tests I was reliably getting back a tagged pointer for what the runtime thought was NSMutableData).

Long story short: you can't do it anymore.

like image 110
CodaFi Avatar answered Dec 02 '22 10:12

CodaFi