What if I want to assign a property to itself?

There are some good workarounds but there is little point in doing that. If a programmer (future maintainer of the code) sees code like this:

a = a

They will remove it.

Such a statement (or a workaround) should never appear in your code.

If your property looks like this:

var a: Int {
   didSet {
      // code
   }
}

then it's a not a good idea to invoke the didSet handler by assignment a = a.

What if a future maintainer adds a performance improvement to the didSet like this?

var a: Int {
   didSet {
      guard a != oldValue else {
          return
      }

      // code
   }
}

The real solution is to refactor:

var a: Int {
   didSet {
      self.updateA()
   }
}

fileprivate func updateA() {
   // the original code
}

And instead of a = a directly call updateA().

If we are speaking about outlets, a suitable solution is to force the loading of views before assigning for the first time:

@IBOutlet weak var photographerLabel: UILabel?

var photographer: Photographer? {
    didSet {
        _ = self.view // or self.loadViewIfNeeded() on iOS >= 9

        photographerLabel?.text = photographer.name // we can use ! here, it makes no difference
    }
}

That will make the code in viewDidLoad unnecessary.

Now you might be asking "why should I load the view if I don't need it yet? I want only to store my variables here for future use". If that's what you are asking, it means you are using a view controller as your model class, just to store data. That's an architecture problem by itself. If you don't want to use a controller, don't even instantiate it. Use a model class to store your data.


Prior to Swift 3.1 you could assign the property name to itself with:

name = (name)

but this now gives the same error: "assigning a property to itself".

There are many other ways to work around this including introducing a temporary variable:

let temp = name
name = temp

This is just too fun not to be shared. I'm sure the community can come up with many more ways to do this, the crazier the better

class Test: NSObject {
    var name: String? {
        didSet {
            print("It was set")
        }
    }

    func testit() {
        // name = (name)    // No longer works with Swift 3.1 (bug SR-4464)
        // (name) = name    // No longer works with Swift 3.1
        // (name) = (name)  // No longer works with Swift 3.1
        (name = name)
        name = [name][0]
        name = [name].last!
        name = [name].first!
        name = [1:name][1]!
        name = name ?? nil
        name = nil ?? name
        name = name ?? name
        name = {name}()
        name = Optional(name)!
        name = ImplicitlyUnwrappedOptional(name)
        name = true ? name : name
        name = false ? name : name
        let temp = name; name = temp
        name = name as Any as? String
        name = (name,0).0
        name = (0,name).1
        setValue(name, forKey: "name") // requires class derive from NSObject
        name = Unmanaged.passUnretained(self).takeUnretainedValue().name
        name = unsafeBitCast(name, to: type(of: name))
        name = unsafeDowncast(self, to: type(of: self)).name
        perform(#selector(setter:name), with: name) // requires class derive from NSObject
        name = (self as Test).name
        unsafeBitCast(dlsym(dlopen("/usr/lib/libobjc.A.dylib",RTLD_NOW),"objc_msgSend"),to:(@convention(c)(Any?,Selector!,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject
        unsafeBitCast(class_getMethodImplementation(type(of: self), #selector(setter:name)), to:(@convention(c)(Any?,Selector!,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject
        unsafeBitCast(method(for: #selector(setter:name)),to:(@convention(c)(Any?,Selector,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject 
        _ = UnsafeMutablePointer(&name)
        _ = UnsafeMutableRawPointer(&name)
        _ = UnsafeMutableBufferPointer(start: &name, count: 1)
        withUnsafePointer(to: &name) { name = $0.pointee }

        //Using NSInvocation, requires class derive from NSObject
        let invocation : NSObject = unsafeBitCast(method_getImplementation(class_getClassMethod(NSClassFromString("NSInvocation"), NSSelectorFromString("invocationWithMethodSignature:"))),to:(@convention(c)(AnyClass?,Selector,Any?)->Any).self)(NSClassFromString("NSInvocation"),NSSelectorFromString("invocationWithMethodSignature:"),unsafeBitCast(method(for: NSSelectorFromString("methodSignatureForSelector:"))!,to:(@convention(c)(Any?,Selector,Selector)->Any).self)(self,NSSelectorFromString("methodSignatureForSelector:"),#selector(setter:name))) as! NSObject
        unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setSelector:")),to:(@convention(c)(Any,Selector,Selector)->Void).self)(invocation,NSSelectorFromString("setSelector:"),#selector(setter:name))
        var localVarName = name
        withUnsafePointer(to: &localVarName) { unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setArgument:atIndex:")),to:(@convention(c)(Any,Selector,OpaquePointer,NSInteger)->Void).self)(invocation,NSSelectorFromString("setArgument:atIndex:"), OpaquePointer($0),2) }
        invocation.perform(NSSelectorFromString("invokeWithTarget:"), with: self)
    }
}

let test = Test()
test.testit()