2

I try to associate a string to the UIViewController ,and the code fails to associate "key" to UIViewController

private var key: Void?

objc_setAssociatedObject(self, &key, "key",.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
print(objc_getAssociatedObject(self, &key) as? String)

here self is UIViewController and key is a void?

This is a demo i found,the key is not defined,but the code works

class MyClass {

    func printTitle(input: MyClass) {
        if let title = input.title {
            print("Title: \(title)")
        } else {
            print("nil")
        }
    }
}

// MyClassExtension.swift
private var key: Void?

extension MyClass {
    var title: String? {
        get {
            return objc_getAssociatedObject(self, &key) as? String
        }

        set {
            objc_setAssociatedObject(self,
                                     &key, newValue,
                                     .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}
Henson Fang
  • 1,177
  • 7
  • 30
  • 1
    Where is `key` declared? It must either be global or static in order for it to have a unique and stable pointer value (and therefore to be used as a key for an associated object) – Hamish Jun 16 '17 at 11:17
  • @Hamish,i edited my question – Henson Fang Jun 16 '17 at 11:19
  • @Hamish,the key in demo is undeclared – Henson Fang Jun 16 '17 at 11:21
  • No, the `key` global variable is declared, and because it's `Void?` (an optional), it will have a default value of `nil`. But the *value* of the property itself is irrelevant – all that matters is that it resides at a unique memory address, which is what is used as the key for the associated object. – Hamish Jun 16 '17 at 11:24
  • But why are you showing us the code that works? Please show us the code that doesn't work! – Hamish Jun 16 '17 at 11:25
  • @Hamish: *"It must either be global or static in order for it to have a unique and stable pointer value"* – that's what I experienced as well, but I wonder if it is documented. – Martin R Jun 16 '17 at 11:27
  • 1
    @HensonFang: See for example https://stackoverflow.com/questions/24133058/is-there-a-way-to-set-associated-objects-in-swift for working implementations. – Martin R Jun 16 '17 at 11:29
  • 1
    @MartinR It was never (as far as I'm aware) officially documented, but it was mentioned in a blog post from the Swift team, which I quote here: https://stackoverflow.com/q/42829907/2976878 – Hamish Jun 16 '17 at 11:29
  • @Hamish,the code that doesn't work is the first code segment – Henson Fang Jun 19 '17 at 04:37
  • @Hamish,i replace the `void?` with `UnsafeRawPointer.init(bitPattern: 0)`,it works,but i still don't know why the demo that uses `void?` works,and my code does not work. – Henson Fang Jun 19 '17 at 04:40
  • @HensonFang But you never answered my first question about the first code segment – where is `key` declared? Almost certainly you declared it as an instance property of your view controller, which won't work. Please show us a [mcve] of your first code segment. – Hamish Jun 19 '17 at 10:05
  • @Hamish,yes , `void?`is not declared ,but the demo does also not declare `void?`,it's just a property – Henson Fang Jun 19 '17 at 10:46
  • @HensonFang I don't know what you mean by "not declared" – `private var key: Void?` *is* a declaration (that also implicitly initialises to `nil`). If `key` is an instance property – then that's your problem. It either needs to be global, or a `static` stored property, as said in my first comment. – Hamish Jun 19 '17 at 10:49

0 Answers0