Automatic Reference Counting (ARC) — sistema ng pamamahala ng memorya sa Swift at Objective-C na awtomatikong nagbibilang ng bilang ng mga referensiya sa bawat bagay at naglalabas nito kapag ang bilang ay umabot sa sero. Ayon sa Apple Swift Documentation, 2026, ang ARC ay naka-embed sa kompiler at gumagana sa yugto ng kompilasyon, naglalagay ng mga tawag na retain/release sa mga tamang lugar. Hindi tulad ng Garbage Collection, ang ARC ay hindi nangangailangan ng hiwalay na thread ng kolektor at hindi lumilikha ng mga pause habang isinasagawa ang aplikasyon.
Mga Pangunahing Punto
ARC (Automatic Reference Counting) — ay isang mekanismo ng pamamahala ng memorya sa antas ng kompiler, na ipinakilala ng Apple sa Xcode 4.2 (2011) para sa Objective-C at minana ng Swift. Hindi tulad ng manu-manong pamamahala ng memorya (Manual Retain-Release, MRR), ganap na ina-automate ng ARC ang mga tawag na retain, release, at autorelease, na inilalagay ang mga ito sa yugto ng kompilasyon nang walang partisipasyon ng developer.
Ang ARC ay hindi garbage collector. Ito ay isang static na pagsusuri na may dinamikong pagpasok ng code: sinusuri ng kompiler ang buhay ng mga bagay at inilalagay ang retain/release sa mga punto kung saan ang mga bagay ay nilikha, kinopya, o lumabas sa saklaw. Ang resulta — deterministikong pagpapakawala ng memorya: ang bagay ay tinatanggal eksakto sa sandaling wala nang referensiya dito, nang walang pagkaantala at pause.
Ayon sa WWDC 2011 Session 323, ang paglipat mula MRR patungong ARC ay nagbawas ng bilang ng crash-bug na may kaugnayan sa memorya ng 70% sa mga aplikasyon ng Apple. Ang mga developer ay tumigil sa manu-manong pag-balance ng retain/release, na nag-alis ng isang buong klase ng leak at double-free error.
Bawat bagay sa memorya ay may bilang ng referensiya (retain count). Sa paglikha ng bagay, ang bilang ay itinakda sa 1. Kapag ang isang bagong strong-referensiya ay tumuturo sa bagay — ang bilang ay tumataas (retain). Kapag nawala ang strong-referensiya — ang bilang ay bumababa (release). Sa pag-abot ng sero, ang bagay ay agad na deallocated.
Ang Swift kompiler ay hindi naglalagay ng retain/release sa bawat pagtatalaga — gumagamit ito ng static na pagsusuri para sa optimisasyon. Halimbawa, kung ang isang bagay ay garantisadong hindi gagamitin pagkatapos ng paglipat, maaaring laktawan ng kompiler ang sobrang release/retain. Ang optimisasyong ito ay tinatawag na ARC Optimisation.
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) na-initialize (retain count: 1)")
}
deinit {
print("\(name) na-deallocate")
}
}
func testARC() {
let p = Person(name: "Alice") // retain count = 1
let q = p // retain count = 2
// q ay lumabas sa saklaw
// retain count = 1
// p ay lumabas sa saklaw
// retain count = 0 → deinit
}
Sa halimbawang ito makikita kung paano pinamamahalaan ng ARC ang bilang: sa pagtatalaga q = p, ang bilang ay tumataas, sa paglabas ng q mula sa saklaw — bumababa. Kapag nawala ang huling strong-referensiya, ang deinitializer ay agad na tinatawag. Walang garbage collector na naghihintay — ang memorya ay agad na pinakawalan.
Ang ARC at Garbage Collection ay lumulutas ng parehong gawain — awtomatikong pamamahala ng memorya — ngunit may mga fundamental na magkaibang approach. Ang pagpili sa pagitan nila ay nagtatakda ng arkitektura ng wika: Swift (ARC) vs Java/Go (GC). Tingnan natin ang mga pangunahing pagkakaiba.
| Katangian | ARC (Swift/ObjC) | GC (Java/Go) |
|---|---|---|
| Sandali ng pagpapakawala | Deterministic: agad kapag sero ang bilang | Hindi deterministiko: sa susunod na koleksiyon |
| Mga pause sa pagpapatupad | Wala (mga pagpasok retain/release sa kompilasyon) | May Stop-The-World pause (2–200 ms) |
| Overhead | Pagtaas/pagbaba ng bilang sa bawat referensiya | Pagtawid sa graph ng bagay, pagmamarka, pagpapakawala |
| Mga problema | Retain Cycle (manu-manong paglutas) | Fragmentasyon ng heap, leak sa nakalimutang referensiya |
| Karagdagang thread | Hindi kinakailangan | Kinakailangan ang thread ng garbage collector |
Ang pangunahing kompromiso: ARC ay nagbibigay ng inaasahang buhay ng mga bagay at serong pause, ngunit nangangailangan ng pag-unawa sa retain cycle at tamang pagpili ng weak/unowned. Ang GC ay nagpapalaya mula sa mga alalahaning ito, ngunit sa halaga ng hindi deterministikong pause at karagdagang thread.
Ang ARC ay tumutukoy ng tatlong uri ng kwalipikador ng referensiya, bawat isa ay naiiba ang epekto sa bilang at siklo ng buhay ng bagay. Ang tamang pagpili ng kwalipikador ay pundasyon ng ligtas na pagtatrabaho sa memorya sa Swift.
Strong — ang default na kwalipikador. Bawat strong-referensiya ay nagtataas ng retain count ng bagay ng 1. Hangga’t mayroong kahit isang strong-referensiya, ang bagay ay buhay. Lahat ng property ng klase at lokal na variable sa Swift ay default na strong. Ang mga strong-referensiya ay lumilikha ng relasyon ng pagmamay-ari: bagay A ay nagmamay-ari ng bagay B.
Weak — referensiya na hindi nagtataas ng retain count. Ang bagay ay maaaring deallocated kahit na may weak-referensiya na tumuturo dito. Pagkatapos ng dealokasyon, ang weak-referensiya ay awtomatikong itinatakda sa nil. Ang weak-referensiya ay palaging idineklara bilang var na may opsyonal na uri (?). Ginagamit ito upang putulin ang retain cycle, lalo na sa pattern ng delegate.
Unowned — hindi nagmamay-aring referensiya na, tulad ng weak, ay hindi nagtataas ng retain count. Gayunpaman, ang unowned-referensiya ay hindi itinatakda sa nil pagkatapos ng dealokasyon — ang pag-access sa pinalayang bagay ay nagdudulot ng crash. Ang Unowned ay ginagamit kapag garantisado na ang bagay ay nabubuhay nang hindi bababa sa referensiyang bagay. Karaniwang senaryo — mga closure at relasyon ng magulang-anak na may garantisadong buhay.
class Customer {
let name: String
var card: CreditCard? // strong
init(name: String) { self.name = name }
deinit { print("\(name) na-deallocate") }
}
class CreditCard {
let number: String
unowned let customer: Customer // unowned — hindi nagmamay-ari
init(number: String, customer: Customer) {
self.number = number
self.customer = customer
}
deinit { print("Card \(number) na-deallocate") }
}
var customer: Customer? = Customer(name: "Bob")
customer?.card = CreditCard(number: "1234", customer: customer!)
customer = nil
// Customer at CreditCard parehong pinakawalan — walang retain cycle
Dito ang CreditCard ay gumagamit ng unowned-referensiya sa Customer. Ang Customer ay nagmamay-ari ng card (strong), at ang card ay hindi nagmamay-ari ng customer (unowned). Kapag ang Customer ay naging nil, parehong bagay ay pinakawalan — walang retain cycle na nalikha. Kung ang card.customer ay strong, ang siklo ay haharang sa pagpapakawala.
Sa kabila ng automation, ang ARC ay hindi panlunas sa lahat. Ang mga developer ay nakakaranas ng ilang karaniwang problema na nangangailangan ng pag-unawa sa panloob na mekanismo ng pamamahala ng memorya.
Mga Closure sa Swift ay kumukuha ng mga panlabas na variable sa pamamagitan ng strong-referensiya. Kung ang isang closure ay itinalaga sa property ng klase at kumukuha ng self — nagkakaroon ng retain cycle: hawak ng klase ang closure, hawak ng closure ang self. Solusyon — capture list na may weak o unowned.
class NetworkManager {
var completionHandler: ((Data?) -> Void)?
var data: Data?
func fetchData() {
completionHandler = { [weak self] result in
guard let self else { return }
self.data = result
self.processResult()
}
}
func processResult() { }
}
Ang capture list [weak self] ay lumilikha ng weak-referensiya sa self sa loob ng closure. Ito ay pumutol sa potensyal na retain cycle. Ang guard let self ay ginagarantiyang buhay ang bagay bago isagawa ang code. weak self — karaniwang praktika para sa asynchronus na closure sa Swift.
Kahit na ang retain/release ay magaan na operasyon, ang madalas na pagtaas/pagbaba ng bilang sa mainit na loop ay lumilikha ng overhead. Sa Swift 5.9+, gumagamit ang kompiler ng optimisasyon, kung saan ang sobrang retain/release ay tinatanggal kung mapapatunayan ng analyzer ang kaligtasan. Gayunpaman, sa Objective-C ang retain/release ay maaari pa ring maging bottleneck sa mga high-load na senaryo na may milyun-milyong tawag bawat segundo.
Autorelease Pool — mekanismo ng naantalang release, ginagamit sa Objective-C at ilang senaryo ng Swift. Ang mga bagay ay inilalagay sa pool at nakakatanggap ng release sa pag-drain ng pool. Sa mga loop na may maraming pansamantalang bagay (halimbawa, pag-parse ng JSON), ang paggawa ng sariling autoreleasepool ay nagbabawas ng peak consumption ng operational memory.
Mga Madalas Itanong
Sa manu-manong pamamahala (MRR), ang developer ay tahasang tumatawag ng retain, release, at autorelease. Ang ARC ay awtomatikong naglalagay ng mga tawag na ito sa yugto ng kompilasyon, na nag-aalis ng panganib ng double-free, leak dahil sa nakalimutang release, at error sa pag-balance ng retain/release.
Ang ARC ay namamahala lamang ng mga Objective-C na bagay at Swift class. Para sa mga istruktura at pointer ng C/C++, hindi inilalapat ang ARC — ang mga bagay na ito ay pinamamahalaan nang manu-mano o sa pamamagitan ng C++ smart pointer (shared_ptr, unique_ptr). Ang mga bagay ng Core Foundation (CFString, CGColor) ay hindi rin sakop ng ARC.
weak — kapag ang bagay ay maaaring ma-deallocate bago ang referensiyang bagay (mga delegate, asynchronus na closure). unowned — kapag garantisadong ang bagay ay nabubuhay nang hindi bababa sa referensiyang bagay (magulang-anak, kung saan ang anak ay hindi maaaring umiral nang walang magulang). Kung hindi sigurado — piliin ang weak.
Mga existential type (protocol as type) sa Swift ay nagba-package ng halaga sa isang espesyal na lalagyan (existential container). Pinapataas nito ang bilang ng retain/release sa mga hangganan ng protocol. Sa Swift 5.7+, ang opaque result types at some parameter ay nagbabawas ng overhead sa pamamagitan ng pag-alis ng lalagyan.
Walang direktang API para basahin ang retain count sa Swift — ito ay itinuturing na detalye ng implementasyon. Para sa diagnosis, gamitin ang Instruments (Allocations, Leaks) o Memory Debugger sa Xcode. Ang mga tool na ito ay nagpapakita ng bilang ng buhay na instance ng klase at mga retention chain.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din