Search code examples
swiftoopswift-protocolsprotocol-oriented

Does protocol array elements passed by value or reference?


I know Structs are passed by value and classes are passed by reference in Swift.

I wonder if I create an array store elements which providing a protocol. These elements passed by value or reference?

Is it based on the definition of model a class or struct?

class ClassA: ProtocolA {
// something
}

struct StructA: ProtocolA {
// something
}

var arr: [ProtocolA] = [ClassA(), StructA()]

exampleFunction(arr[0]) // is it passed by reference
exampleFunction(arr[1]) // is it passed by value


Solution

  • Protocols should be seen as value types because you need to explicitly tell the compiler that it is a reference type by defining it as conforming to AnyObject (which all classes conform to)

    So if you have

    protocol ProtocolB: AnyObject
    

    then any type conforming to ProtocolB will be sent by reference and otherwise not.

    Here is a simplified example

    protocol ProtocolA {
        var x: Int { get set }
    }
    
    protocol ProtocolB: AnyObject {
        var y: Int { get set }
    }
    
    class ClassA: ProtocolA, ProtocolB {
        var x = 0
        var y = 0
    }
    
    func exampleFunction(_ object: ProtocolA) {
        object.x += 2 // <-- This will generate a compilation error
    }
    
    func exampleFunction(_ object: ProtocolB) {
        object.y += 2 // This is fine
    }