12

I would like to have a pointer as a parameter of a class. But when I am trying to code the init, I am having this error: Cannot pass immutable value of type 'AnyObject?' as inout argument

class MyClass {
    var valuePointer: UnsafeMutablePointer<AnyObject?>

    init(value: inout AnyObject?) {
        self.valuePointer = &value
    }
}

I would like to create some instance of MyClass which can all refer to the same "value". Then, when I am editing this value in this class, it would change everywhere else.

This is the first time I'm working with pointer in Swift. I guess I am doing it wrong...

Tulleb
  • 8,195
  • 8
  • 24
  • 48

4 Answers4

18

For those who has the cannot pass immutable value as inout argument error. Check that your argument is not optional first. Inout type doesn't seems to like optional values.

Tulleb
  • 8,195
  • 8
  • 24
  • 48
  • This fixed my problem on Linux Swift. Thanks! The full error message: _error: cannot pass immutable value as inout argument: implicit conversion **from '[String : Any?]' to '[String : Any?]?'** requires a temporary_ should have tipped me off: by changing the signature inout parameter to [String: Any], the compiler didn't complain anymore. – PJ_Finnegan Oct 09 '17 at 17:04
3

You could send the pointer when initializing the object:

class MyClass {
    var valuePointer: UnsafeMutablePointer<AnyObject?>

    init(value: inout UnsafeMutablePointer<AnyObject?>) {
        self.valuePointer = value
    }
}

Just add the pointer reference when initializing MyClass:

let obj = MyClass(value: &obj2)
andriosr
  • 441
  • 3
  • 11
  • Thanks @andriosr, I tried that but then I have another issue when I initializing my class: `Cannot convert value of type 'String?' to expected argument type 'UnsafeMutablePointer'`. I am doing: `let obj = MyClass(value: &firstName)`(which is a String?). I don't see why... – Tulleb Jul 27 '16 at 16:27
  • 1
    I think I found my answer. Apparently I have to cast it first. It isn't as simple as adding a `&` before... Here is the code I found: `UnsafeMutablePointer(((firstName)! as NSString).utf8String!))` – Tulleb Jul 27 '16 at 16:58
  • Thats great! Please, post it yourself or let me know if you want me update my answer with this resolution so others can take advantage of it :) – andriosr Jul 27 '16 at 17:04
  • I already accepted your answer. The fact that it didn't work out with a String reference is another problem so I don't think you need to edit anything. Thanks for your help! – Tulleb Jul 27 '16 at 17:07
  • Hmm... Actually my "solution" doesn't seem to work so great. I am having an EXC_BAD_ACCESS now. Still working on it... – Tulleb Jul 27 '16 at 17:09
  • It has EXC_BAD_ACCESS because the pointer memory is unallocated soon after it's use. I guess I would need to put it into a variable to keep it allocated, but I can't do that in my project. – Tulleb Aug 01 '16 at 09:12
  • Are you explicitly deallocating it or is swift doing so? Try using Deinitialization: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html – andriosr Aug 01 '16 at 12:51
1

For someone faced the same issue with me:

Cannot pass immutable value as inout argument: implicit conversion from '' to '' requires a temporary

The code as below:

protocol FooProtocol {
    var a: String{get set}
}

class Foo: FooProtocol {
    var a: String
    init(a: String) {
        self.a = a
    }
}

func update(foo: inout FooProtocol) {
    foo.a = "new string"
}

var f = Foo(a: "First String")
update(foo: &f)//Error: Cannot pass immutable value as inout argument: implicit conversion from 'Foo' to 'FooProtocol' requires a temporary

Change from var f = Foo(a: "First String") to var f: FooProtocol = Foo(a: "First String") fixed the Error.

lee
  • 7,016
  • 8
  • 41
  • 56
0

For me, I had a class variable defined like this:

// file MyClass.swift

class MyClass{

    var myVariable:SomeClass!

    var otherVariable:OtherClass!

    ...

    func someFunction(){
        otherVariable.delegateFunction(parameter: &myVariable) // error
    }
}

// file OtherClass.swift
class OtherClass{
    func delegateFunction(parameter: inout myVariable){
        // modify myVariable's data members 
    }
}

There error that was invoked was:

Cannot pass immutable value as inout argument: 'self' is immutable

I then changed my variable declaration in MyClass.swift to no longer have ! and instead initially point to some dummy instance of a class.

var myVariable:SomeClass = SomeClass() 

My code was then able to compile and run as intended. So... somehow having the ! on a class variable prevents you from passing that variable as an inout variable. I do not understand why.

SomeGuy
  • 959
  • 10
  • 13