How does "public private(set)" access modifiers work?
Asked Answered
B

5

62

So I'm going through the Apple docs here - Apple Docs

Then I ran into this:

public struct TrackedString {
    public private(set) var numberOfEdits = 0
    public var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
    public init() {}
}

How does adding public private(set) exactly work? If you can show some easier examples/explanation that would be amazing!

Bannerol answered 16/5, 2016 at 23:35 Comment(0)
S
80

This just means that the getter for numberOfEdits is public, but the setter is private. There's nothing more to it.

The reason in this case is so that you can read numberOfEdits publicly, but you can only set it via changing value. If it were fully public, then anyone could set it, but if it were only settable, then the didSet in value couldn't modify it. private(set) is a compromise between those two.

Sonnysonobuoy answered 16/5, 2016 at 23:48 Comment(2)
The explanation is correct, but the variable mentioned is wrong. The numberOfEdits property is the one that can be set only from within the class (i.e. read-only everywhere else). The value property is still read/write everywhere.Circumnutate
@conarch "The numberOfEdits property is the one that can be set only from within the class" Not the class. The file. Class scoping of privacy has not yet been implemented in Swift.Gulfweed
C
27

This property can be read, but cannot be set from the outside.

You assign a lower access level by writing private(set).

Its works like Public getter and Private setter.

//MARK:- Foo
class Foo {
    private var name: String
    private var ID: String

   //initialize
   init(name:String, ID:String){
      self.name = name
      self.ID = ID
   }
}

We will get an error when to try to access private variable.

privateAccessLevel

But we can fix this error in a single line by changing private access level to private(set).

//MARK:- Foo
class Foo {
    private(set) var name: String
    private var ID: String

   //initialize
   init(name:String, ID:String) {
       self.name = name
       self.ID = ID
   }
}

So you can easy access the private variable, constant, property, or subscript.

//Access class value from Foo
let fooObjc = Foo.init(name: "test", ID: "9900")
print(fooObjc.name)

Use fileprivate(set), private(set), and internal(set) to change the access level of this synthesized setter in exactly the same way as for an explicit setter in a computed property.

This property can be read, but cannot be set from the outside.

Ref: Click the link to know more

Claxton answered 18/4, 2020 at 8:9 Comment(2)
In your last example private(set) var is actually let. – private(set) var is only useful if the value is going to be modified inside the class (the init method doesn't count).Bridwell
It worked for me, thanks a lot for the help. Moreover, if you want this var to be readable (Objective-C and Swift) publically and settable privately then you can do the following: @objc public private(set) var myVar: String = ""Semmes
C
5

private (set) var limits write access to internal scope, but still allows external read access. The var can also be read internally.

For example, compare private var to private (set) var:

private

class NameNotAccessible {
    private var name: String?
}

var person = NameNotAccessible()
print(person.name) // ERROR: external access forbidden

Modified to private (set) var

class NameAccessible {
    private (set) var name: String? // externally readable, internally writable
}

var person2 = NameAccessible()
print(person2.name) // external read OK
person2.name = "Jacob" // ERROR: external write forbidden
Childbirth answered 30/9, 2022 at 19:41 Comment(0)
S
1

Thanks, @Sivabalaa Jothibose and @craft It worked for me, thanks a lot for the help.

Moreover, if you want this var to be readable (Objective-C and Swift) publically and settable privately then you can do the following:

@objc public private(set) var myVar: String = ""
Semmes answered 21/2, 2023 at 15:6 Comment(0)
Y
-1

You can try this, value property can be read, but cannot be set from the outside.

public var value: String {
    _value
}

private var _value = ""
Yenta answered 17/7, 2024 at 13:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.