Immutable value as inout argument
Asked Answered
R

5

15

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...

Retroversion answered 27/7, 2016 at 14:23 Comment(0)
R
21

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.

Retroversion answered 1/8, 2016 at 9:35 Comment(2)
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.Strop
You can just make a copy with a new variable and it will work with an optional fyiPiteous
Z
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)
Zionism answered 27/7, 2016 at 15:7 Comment(7)
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<AnyObject?>'. I am doing: let obj = MyClass(value: &firstName)(which is a String?). I don't see why...Retroversion
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<AnyObject?>(((firstName)! as NSString).utf8String!))Retroversion
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 :)Zionism
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!Retroversion
Hmm... Actually my "solution" doesn't seem to work so great. I am having an EXC_BAD_ACCESS now. Still working on it...Retroversion
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.Retroversion
Are you explicitly deallocating it or is swift doing so? Try using Deinitialization: developer.apple.com/library/ios/documentation/Swift/Conceptual/…Zionism
G
2

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.

Glycogen answered 27/3, 2019 at 7:48 Comment(0)
M
1

For me i am passing the direct value in the function calling like this.

    public func testInout(_ a :  inout [Int]) -> Int {
        return a.reduce(0, +) 
    }

testInout(&[1,2,4]) // Getting the error :- Cannot pass immutable value of type '[Int]' as inout argument. Because by default the function parameters are constant.

To remove the above error you need the pass the array which has the var type. Like below.

 var arr = [1, 2, 3] 
   public func testInout(_ a :  inout [Int]) -> Int {
            return a.reduce(0, +) 
        }
    
    testInout(&arr)
Massenet answered 19/6, 2021 at 9:53 Comment(0)
S
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.

Syllabic answered 28/6, 2018 at 22:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.