1. Giriş

Swift’te access control (erişim kontrolü), kodun farklı bölümlerinin birbirinden nasıl izole edildiğini belirler.
private(set) ise bu erişim kontrol mekanizmalarının çok kullanışlı ama bazen gözden kaçan bir üyesidir.

Temel olarak:

private(set) var propertyName: PropertyType

Yani, getter herkese açık (internal varsayılan) olurken, setter yalnızca tanımlandığı erişim seviyesinde (ör. private) görünür.


2. Neden Kullanılır?

private(set) kullanmanın en büyük faydası encapsulation’dır (kapsülleme).
Bir değişkenin değerini dış dünyaya göstermek isteriz ama değiştirilmesini istemeyiz. Bu, özellikle state management veya immutable interface tasarımlarında önemlidir.


3. Temel Örnek

Örnek 1 — Sayaç

class Counter {
private(set) var count = 0

func increment() {
count += 1
}
}

let counter = Counter()
print(counter.count) // 0 — Okuyabiliriz
counter.increment()
print(counter.count) // 1

// counter.count = 10 ❌ HATA: 'count' setter is inaccessible

Burada count değeri dışarıdan değiştirilemez ama okunabilir.
Sadece Counter sınıfının içinden güncellenebilir.


4. Stored Property ve Computed Property Farkı

4.1 Stored Property (Depolanan Özellik)

struct Player {
private(set) var score = 0
mutating func add(points: Int) {
score += points
}
}

4.2 Computed Property (Hesaplanan Özellik)

struct Rectangle {
var width: Double
var height: Double

private(set) var area: Double {
get { width * height }
set { width = sqrt(newValue); height = sqrt(newValue) } // setter sınırlı
}
}

📌 Fark: Stored property’de değer saklanır, computed property’de saklanmaz; private(set) sadece setter erişim seviyesini kısıtlar, stored/computed ayrımı bu mantığı değiştirmez.
Ama stored property’de direkt bir “value” vardır, computed’da “hesaplama” vardır.


5. İleri Düzey Kullanımlar

Örnek 2 — State Yönetimi

class ViewModel {
private(set) var isLoading = false

func loadData() {
isLoading = true
// API isteği...
isLoading = false
}
}

Burada UI tarafı isLoading değerini gözlemleyebilir, ama değiştiremez.
Bu, View → ViewModel bağımlılığını güvenli hale getirir.


Örnek 3 — Koleksiyon Yönetimi

struct ShoppingCart {
private(set) var items: [String] = []

mutating func addItem(_ item: String) {
items.append(item)
}
}

var cart = ShoppingCart()
cart.addItem("Elma")
print(cart.items) // ["Elma"]
// cart.items.append("Armut") ❌ HATA

items sadece ShoppingCart içinde değiştirilebilir, dışarıya immutable bir koleksiyon gibi görünür.


6. private(set) ile Diğer Erişim Seviyeleri

private(set) tek başına kullanılmaz; erişim seviyeleri ile kombine edilebilir:

TanımAnlamı
private(set)Setter sadece aynı dosya/extension içinde kullanılabilir
fileprivate(set)Setter sadece aynı dosya içinde kullanılabilir
internal private(set)Getter her yerden okunur (internal), setter sadece aynı dosya/extension içinde
public private(set)Getter public, setter private
open private(set)Getter open, setter private

Örnek:

public private(set) var status: String = "Idle"

Bu sayede framework kullanıcısı status’u okuyabilir ama değiştiremez.


7. Alternatif Yöntemler

class Example {
private var _value: Int = 0
var value: Int { _value }
}

private(set) bunu daha kısa yapmanın bir yoludur.

struct ImmutableCounter {
let count: Int
func increment() -> ImmutableCounter {
ImmutableCounter(count: count + 1)
}
}

Bu tamamen farklı bir yaklaşım ama mantık aynı: dışarıdan değiştirme engellenir.


8. Sonuç

private(set) Swift’te hem temiz kod hem de güvenli state yönetimi için kritik bir araçtır.

Özellikle MVVM, VIPER gibi mimarilerde ViewModel → View veri akışında çokça kullanılır.