64

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!

5 Answers 5

81

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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

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

2 Comments

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).
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 = ""
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 

Comments

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 = "" 

Comments

-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 = "" 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.