حافظه (Swift Memory)
اینجا درباره «حافظه سویفت (Swift Memory)» حرف می زنیم. یعنی مدیریت ساخت و جمع آوری اشیاء. قهرمان اصلی «ARC» است. همچنین با «weak/unowned» و «closure capture» چرخه نگه داری را می شکنیم. مثل کلاس، دفترها را قرض می دهی؛ وقتی کسی نگه ندارد، برمی گردند.
ARC خودکار در کلاس ها
«شمارنده ارجاع خودکار (ARC)» تعداد ارجاع های قوی را می شمارد. وقتی ارجاع قوی نماند، شی آزاد می شود. کلاس «reference type» است، پس ARC برایش حیاتی است.
class Box {
let name: String
init(_ n: String) {
name = n
print("init \(n)")
}
deinit {
print("deinit \(name)")
}
}
do {
let b = Box("A")
print("in scope")
}
print("after scope")
نکته: اگر دنبال مرور سریع «حافظه سویفت» هستی، این صفحه حافظه سویفت مرجع جمع وجور توست.
چرخه ارجاع قوی و راه حل
«چرخه ارجاع قوی (Retain Cycle)» یعنی دو شی هم دیگر را محکم نگه دارند. ARC نمی تواند آزاد کند. یک سمت را weak یا گاهی unowned بگذار تا حلقه بشکند.
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit {
print("Person deinit")
}
}
class Apartment {
let unit: String
weak var tenant: Person?
init(unit: String) {
self.unit = unit
}
deinit {
print("Apartment deinit")
}
}
do {
var john: Person? = Person(name: "John")
var unit: Apartment? = Apartment(unit: "4A")
john!.apartment = unit
unit!.tenant = john
john = nil
unit = nil
}
Closureها و لیست Capture
«Closure» متغیرها را می گیرد. اگر یک کلاس Closure را نگه دارد و داخلش self را صدا بزند، احتمال چرخه داریم. با [weak self] از چرخه جلوگیری کن.
import Dispatch
class Loader {
var onComplete: (() -> Void)?
func load() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let self = self else {
return
}
print("Finished: \(self)")
self.onComplete?()
}
}
deinit {
print("Loader deinit")
}
}
do {
let loader = Loader()
loader.onComplete = {
print("done callback")
}
loader.load()
}
اگر کدت هم زمان است، ارتباط حافظه و کارهای موازی مهم است. سری هم به هم روندی بزن. برای خطاهای async هم مدیریت خطا را ببین.
گام های عملی
- نمونه ARC را اجرا کن و ترتیب لاگ را ببین.
- weak را حذف کن و چرخه نگه داری را بررسی کن.
- در مثال Closure،
[weak self]را بردار و حافظه را رصد کن.
جمع بندی سریع
- ARC وقتی ارجاع قوی صفر شود، آزاد می کند.
- weak/unowned چرخه ها را می شکنند.
- Closureها متغیر می گیرند؛ حواست به self باشد.
- در کارهای async، آزادسازی زمان مند را درک کن.