Strong Reference (malakas na sanggunian): ano ito, mekanismo ng paggana at ARC

May-akda: IT Sectr Nai-publish: 2026-03-30 Oras ng pagbabasa: 9 min

Strong Reference (malakas na sanggunian) — ay isang pamantayang mekanismo ng pamamahala ng memorya kung saan ang isang bagay ay nananatili sa memorya hangga't mayroong kahit isang aktibong sanggunian na tumuturo dito. Hindi tulad ng mahihinang sanggunian, ang malakas na sanggunian ay nagpapataas ng bilang ng sanggunian ng bagay at pumipigil sa awtomatikong pagpapalaya nito. Ayon sa Apple Developer Documentation, awtomatikong pinamamahalaan ng ARC ang habang-buhay ng mga bagay sa Swift at Objective-C. Ang pag-unawa sa paggana ng malalakas na sanggunian ay mahalaga para maiwasan ang pagtagas ng memorya at mga siklikal na dependency sa mga mobile application.

Mga pangunahing punto

  • Strong Reference — sanggunian na humahawak ng bagay sa memorya, pinapataas ang retain count nito ng 1.
  • ARC awtomatikong naglalagay ng mga operasyong release at retain, inaalis ang manu-manong pamamahala ng memorya sa Swift at Objective-C.
  • Retain cycle nangyayari kapag ang dalawang bagay ay tumutukoy sa isa't isa sa pamamagitan ng malalakas na sanggunian — hindi kailanman nabubuklod ang memorya.
  • Weak Reference hindi pinapataas ang bilang ng sanggunian at awtomatikong nagiging zero kapag nabuklod ang bagay.
  • Unowned Reference hindi pinapataas ang bilang, ngunit ipinapalagay na ang bagay ay hindi nabubuhay nang mas mahaba kaysa sa may-ari.

Ano ang Strong Reference?

Strong Reference — ay isang uri ng sanggunian sa isang bagay na pumipigil sa pagkawasak nito ng tagakolekta ng basura o sistema ng pamamahala ng memorya. Hangga't mayroong kahit isang malakas na sanggunian sa bagay, hindi nabubuklod ang memorya sa ilalim nito. Ito ang pangunahing mekanismo kung saan itinayo ang ARC sa Swift at Objective-C at ang pagkolekta ng basura sa Java at Kotlin.

Ang konsepto ng malakas na sanggunian ay pundamental para sa lahat ng mga wika na may awtomatikong pamamahala ng memorya. Sa mga sistemang may ARC, bawat malakas na sanggunian ay nagpapataas ng bilang ng sanggunian ng bagay. Kapag ang bilang ay bumaba sa zero, ang bagay ay agad na dealokasyon. Sa Java at Kotlin na may tagakolekta ng basura, ginagarantiya ng malakas na sanggunian na ang bagay ay maaabot at hindi kokolektahin ng GC.

Ayon sa datos ng WWDC 2021, humigit-kumulang 35% ng pagtagas ng memorya sa mga iOS application ay nauugnay sa hindi tamang paggamit ng malalakas na sanggunian at mga siklo ng pagpapanatili. Sa pagpapaunlad ng Android, ang pagtagas sa pamamagitan ng implicit strong reference sa mga closure at callback ay ang pangalawang pinakakaraniwang sanhi ng mga problema sa memorya pagkatapos ng Context Leak.

Para sa mabisang pagtatrabaho sa memorya, kinakailangang maunawaan ang pagkakaiba sa pagitan ng strong, weak at unowned na mga sanggunian at piliin nang tama ang uri ng sanggunian batay sa pagmamay-ari at habang-buhay ng mga bagay.

Paano binago ng ARC ang pagdulog sa pamamahala ng memorya

Bago ang pagpapakilala ng ARC, manu-manong tinatawag ng mga developer ang retain at release para sa bawat bagay, na humantong sa maraming error. Ang ARC, na ipinakilala ng Apple noong 2011 sa paglabas ng LLVM 3.0, ay awtomatiko ang prosesong ito sa pamamagitan ng pagsusuri ng graph ng pagmamay-ari sa yugto ng kompilasyon. Ang compiler mismo ang naglalagay ng mga tawag na retain, release at autorelease sa mga tamang lugar.

Ayon sa Clang Static Analyzer, ang pagpapakilala ng ARC ay nagbawas ng bilang ng mga bug na nauugnay sa memorya sa mga iOS application ng 70%. Para sa developer, nangangahulugan ito na ang pamamahala ng memorya ay naging mas ligtas, ngunit kasabay nito ay lumitaw ang pangangailangan na maunawaan kung paano gumagana ang malalakas na sanggunian sa ilalim ng hood — upang maiwasan ang retain cycles.

Sa Kotlin at Java, ang papel ng ARC ay ginagampanan ng tagakolekta ng basura, ngunit ang prinsipyo ng malakas na sanggunian ay nananatiling pareho: GC Roots — ito ang mga entry point kung saan ang mga bagay ay pinananatili ng malalakas na sanggunian. Hangga't ang isang bagay ay maaabot sa pamamagitan ng isang chain ng malalakas na sanggunian mula sa GC Root, hindi ito kokolektahin.

Paano gumagana ang Strong Reference sa ARC?

ARC (Automatic Reference Counting) ay gumagana sa prinsipyo ng pagbibilang ng mga sanggunian para sa bawat bagay sa heap. Kapag ang isang bagong malakas na sanggunian sa bagay ay nilikha, ang bilang ay tumataas (retain). Kapag ang sanggunian ay nawasak o na-overwrite, ang bilang ay bumababa (release). Kapag ang bilang ay umabot sa zero, ang bagay ay agad na tinatanggal mula sa memorya.

Isaalang-alang natin ang isang halimbawa sa Swift. Sa paglikha ng isang instance ng klase, ang ARC ay naglalaan ng memorya at nagtatakda ng retain count sa 1. Bawat bagong pagtatalaga sa ibang variable ay nagpapataas ng bilang. Kapag ang variable ay lumabas sa saklaw, ang bilang ay bumababa:

swift
class ProfileViewController {
    var nameLabel: String?
    var avatarImage: UIImage?

    func loadProfile() {
        // retain count = 1 para sa bagong instance
        let user = User(name: "Ivan")
        // retain count = 2 pagkatapos ng pagtatalaga ng nameLabel
        nameLabel = user.name
        // paglabas ng method — user ay lumabas ng scope, retain count = 1
    }
}

Sa kodigong ito, ginagarantiya ng ARC na ang bagay na User ay nananatili sa memorya hangga't mayroong kahit isang malakas na sanggunian dito. Kapag natapos ang function na loadProfile, ang lokal na variable na user ay nawasak, ngunit hawak pa rin ng nameLabel ang bagay. Ang memorya ay pakakawalan lamang kapag ang nameLabel ay hindi na umiiral o na-overwrite.

Sa Kotlin, ang katulad na pag-uugali ay ibinibigay sa pamamagitan ng GC Roots. Hangga't mayroong isang masusubaybayang chain ng strong references mula sa ugat ng tagakolekta ng basura (halimbawa, isang static field o aktibong thread), ang bagay ay nananatili sa memorya. Ang pagkakaiba ay ang GC ay hindi nagpapalaya ng memorya kaagad — ito ay nangyayari nang asinkrono pagkatapos ng pagsusuri ng abot.

Kailan nangyayari ang pagpapalaya ng memorya

Sa ARC, ang pagpapalaya ay nangyayari nang sabay-sabay sa sandali ng pag-zero ng bilang. Sa Swift at Objective-C, alam mo nang eksakto kung kailan tatanggalin ang bagay. Sa Kotlin at Java, ang sandali ng pagpapalaya ay hindi mahuhulaan, ngunit ito ay binabayaran ng mas nababagong iskema ng pagtuklas ng mga siklikal na dependency sa antas ng tagakolekta ng basura.

Retain Cycles at pagtagas ng memorya

Retain cycle (siklo ng pagpapanatili) — sitwasyon kung saan ang dalawa o higit pang mga bagay ay may magkabilang malalakas na sanggunian sa isa't isa. Bilang resulta, ang kanilang retain count ay hindi bumababa sa zero, at ang memorya ay hindi nabubuklod kahit na pagkatapos na ang mga bagay ay hindi na kailangan ng application.

Klasikong halimbawa: ang parent view controller ay humahawak ng child object na may malakas na sanggunian, at ito naman ay humahawak ng parent na may malakas na sanggunian. Ito ay tipikal para sa mga sitwasyon na may mga delegado, closure at nested lambda expressions. Ayon sa Instruments Leaks, ang retain cycles ay bumubuo ng hanggang 60% ng lahat ng pagtagas ng memorya sa mga application na gumagamit ng ARC.

swift
class ParentViewController: UIViewController {
    var child: ChildViewController?

    func setupChild() {
        child = ChildViewController()
        // retain cycle: parent ay humahawak ng child, child ay humahawak ng parent sa pamamagitan ng closure
        child?.onEvent = {
            self.handleEvent()
        }
    }

    func handleEvent() {}
}

Ang problema dito ay ang closure na onEvent ay kumukuha ng self (ParentViewController) na may malakas na sanggunian, at ang ParentViewController mismo ay humahawak ng child na may malakas na sanggunian. Ang parehong bagay ay hindi kailanman pakakawalan. Ang solusyon — gamitin ang weak self sa closure upang maputol ang siklo.

Sa Kotlin, ang mga katulad na siklo ay lumilitaw kapag gumagamit ng mga lambda na kumukuha ng mga panlabas na bagay. Ang JVM tagakolekta ng basura ay maaaring makakita ng mga ganitong siklo sa paglipas ng panahon, ngunit kung ang mga bagay ay hindi maaabot mula sa GC Roots. Kung ang siklo ay nauugnay sa isang aktibong thread o UI context, ang pagtagas ay nananatili sa buong habang-buhay ng application.

Strong vs Weak vs Unowned Reference

Ang pag-unawa sa pagkakaiba sa pagitan ng mga uri ng sanggunian — susi sa ligtas na pamamahala ng memorya. Strong Reference ay nagpapataas ng retain count. Weak Reference ay hindi nagpapataas ng retain count at awtomatikong nagiging nil kapag nabuklod ang bagay. Unowned Reference ay hindi rin nagpapataas ng retain count, ngunit hindi nagze-zero — ang pagtukoy dito pagkatapos ng pagpapalaya ay nagdudulot ng crash.

Uri ng sanggunianRetain countKaligtasanKailan gagamitin
Strong+1Ligtas (default)Pagmamay-ari ng bagay, relasyong parent → child
WeakHindi nagbabagoAwtomatikong pag-zero (safe)Mga delegado, callback, pabalik na sanggunian
UnownedHindi nagbabagoPeligro ng crash sa huling pagtukoyKapag ang bagay ay garantisadong nabubuhay nang mas mahaba kaysa sa may-ari

Ang pagpili ng uri ng sanggunian ay idinidikta ng relasyon ng pagmamay-ari. Kung ang bagay B ay bahagi ng A at hindi maaaring umiral nang wala ito — gamitin ang Strong. Kung ang B ay maaaring umiral nang nakapag-iisa at tumutukoy sa A para sa mga abiso — gamitin ang Weak. Ang Unowned ay bihirang ginagamit — kung ang habang-buhay ng child object ay mahigpit na hindi lalampas sa habang-buhay ng parent.

Praktikal na tuntunin sa pagpili

Apple Developer Documentation ay nagrerekomenda: bilang default, gamitin ang strong para sa lahat ng relasyon ng pagmamay-ari. Kung kailangan mong iwasan ang retain cycle — tukuyin kung aling sanggunian ang dapat mahina. Karaniwan ito ang pabalik na sanggunian sa hierarchy (child → parent). Sa Kotlin, ang katulad na papel ay ginagampanan ng WeakReference mula sa java.lang.ref, na ginagamit para sa mga cache at pattern ng observer.

Paano ayusin ang mga problema sa malalakas na sanggunian

Ang pagtuklas ng retain cycles — unang hakbang. Ang pangalawa — ang tamang pag-aalis ng mga ito. Ang pangunahing kasangkapan sa paglaban sa mga siklo ng malalakas na sanggunian ay ang pagpapalit ng isa sa mga sanggunian ng weak o unowned. Sa mga wikang may pagkolekta ng basura, karagdagan na inilalapat ang WeakReference na may manu-manong pagsusuri ng null bago ang bawat pag-access.

Sa Swift at Objective-C, ang pinakakaraniwang pag-aayos ay ang pagdaragdag ng [weak self] sa mga closure. Ginagarantiya nito na ang closure ay hindi humahawak sa bagay pagkatapos nitong mapakawalan. Sa Kotlin, para sa mga katulad na layunin ay ginagamit ang WeakReference wrapper o malinaw na paglilinis ng sanggunian sa onDestroy.

swift
class NetworkService {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // pagkuha sa pamamagitan ng weak self — retain cycle ay hindi kasama
        URLSession.shared.dataTask(
            with: URL(string: "https://api.example.com")!
        ) { [weak self] data, response, error in
            guard let self else { return }
            completion(data)
        }.resume()
    }
}

Sa halimbawang ito, ginagarantiya ng [weak self] na ang NetworkService ay hindi hahawakan ng closure pagkatapos na hindi na ito kailangan. Kung ang self ay napakawalan bago matapos ang request — guard let self else { return } ay lumalabas sa closure nang hindi tinatawagan ang completion.

Para sa diagnosis ng retain cycles, gamitin ang Instruments Leaks para sa iOS o Android Profiler + LeakCanary para sa Android. Ang mga tool na ito ay nagpapakita ng eksaktong graph ng pagpapanatili at nagpapahiwatig kung aling malakas na sanggunian ang pumipigil sa pagpapalaya ng bagay. Ang regular na profiling ng memorya ay dapat maging bahagi ng CI/CD pipeline ng bawat mobile project.

Strong Reference sa Swift at Kotlin — paghahambing

Swift at Kotlin ay gumagamit ng fundamental na magkakaibang mekanismo ng pamamahala ng memorya, ngunit ang konsepto ng malakas na sanggunian ay naroroon sa pareho. Sa Swift, inilalapat ang ARC na may sabay-sabay na pagpapalaya sa retain count = 0. Sa Kotlin, ginagamit ang tracing GC na naglilinis nang asinkrono ng mga bagay na hindi maaabot.

ParameterSwift (ARC)Kotlin (JVM GC)
MekanismoPagbibilang ng sanggunian (retain count)Pagsubaybay ng abot (GC Roots)
PagpapalayaSabay-sabay (sa pag-zero ng bilang)Asinkrono (sa pamamagitan ng GC cycle)
Retain cycleHindi awtomatikong natutukoyMaaaring matukoy ng GC, ngunit hindi kaagad
Weak refweak (awtomatikong pag-zero)WeakReference (manu-manong pagsusuri)

Ang pangunahing praktikal na pagkakaiba: sa Swift, ang retain cycle — ay garantisadong pagtagas. Sa Kotlin, maaaring putulin ng GC ang siklo kung ang mga bagay ay hindi maaabot mula sa ugat, ngunit ang habang-buhay ng mga tumagas na bagay ay nananatiling hindi mahuhulaan. Samakatuwid, sa parehong wika, ang pinakamahusay na diskarte ay iwasan ang mga siklo ng malalakas na sanggunian sa yugto ng disenyo.

Para sa Swift, gamitin ang weak sa mga pattern ng delegado at closure. Para sa Kotlin — WeakReference o Lifecycle-aware na mga component na awtomatikong naglilinis ng mga sanggunian sa pagkawasak ng may-ari. Sa parehong diskarte, ang layunin ay pareho — alisin ang malalakas na sanggunian kung saan lumilikha sila ng hindi maputol na chain ng pagpapanatili.

Mga madalas itanong

Paano naiiba ang Strong Reference sa Weak Reference?

Strong Reference ay nagpapataas ng retain count ng bagay at pumipigil sa pagpapalaya nito hangga't umiiral ang sanggunian. Ang Weak Reference ay hindi nagbabago ng retain count at awtomatikong nagze-zero kapag ang bagay ay tinanggal mula sa memorya. Ang malalakas na sanggunian ay ginagamit para sa pagmamay-ari, ang mahihinang sanggunian — para sa mga pabalik na koneksyon at delegado.

Ano ang retain cycle at bakit ito mapanganib?

Retain cycle — isang magkabilang pagharang kung saan ang dalawang bagay ay humahawak sa isa't isa ng malalakas na sanggunian. Ang kanilang retain count ay hindi bumababa sa zero, ang memorya ay hindi nabubuklod. Ito ay humahantong sa pagtagas ng memorya: ang mga bagay ay nananatili sa heap magpakailanman, ang application ay kumokonsumo ng parami nang paraming mapagkukunan at sa kalaunan ay nag-crash sa OutOfMemory.

Paano matukoy ang retain cycle sa isang iOS application?

Gamitin ang Instruments Leaks mula sa Xcode — simulan ang profiling gamit ang Leaks template, isagawa ang scenario sa application at suriin ang mga indikator ng pagtagas. Para sa tumpak na diagnosis, lumipat sa tab na Cycles & Roots — ipapakita nito ang graph ng magkabilang strong reference na bumubuo ng hindi maputol na siklo.

Kailan dapat gamitin ang Unowned sa halip na Weak?

Unowned ay ilapat kapag ang habang-buhay ng child object ay tiyak na hindi lalampas sa habang-buhay ng parent — halimbawa, kapag nagbubuklod ng isang bagay sa isang mahigpit na tinukoy na saklaw. Kung may pag-aalinlangan, gamitin ang Weak, dahil ang pagtukoy sa napakawalan nang unowned ay nagdudulot ng crash ng application.

Nakakaapekto ba ang malalakas na sanggunian sa pagganap ng application?

Hindi direkta — oo. Ang bawat retain at release sa ARC ay isang atomikong operasyon na may overhead. Sa malaking bilang ng mga bagay sa mga siklo, ito ay maaaring makaapekto sa pagganap. Gayunpaman, ang pangunahing problema ay hindi ang bilis ng ARC, ngunit ang pagtagas ng memorya dahil sa maling napiling uri ng sanggunian.

Buod

  • Strong Reference — pangunahing mekanismo ng pagmamay-ari ng bagay, na humahawak nito sa memorya sa pamamagitan ng pagpapataas ng retain count.
  • ARC ay awtomatiko ang pamamahala ng memorya sa Swift at Objective-C, inaalis ang manu-manong retain at release, ngunit hindi pinoprotektahan laban sa retain cycles.
  • Retain cycle ay lumilitaw sa magkabilang malalakas na sanggunian — ito ang pangunahing sanhi ng pagtagas ng memorya sa mga sistema ng ARC.
  • Ang mga sangguniang Weak at Unowned ay pumuputol ng mga siklo ng malalakas na sanggunian nang hindi pinapataas ang retain count.
  • Ang pagpili ng uri ng sanggunian ay tinutukoy ng relasyon ng pagmamay-ari: Strong para sa parent→child, Weak o Unowned para sa child→parent.
  • Instruments Leaks at LeakCanary — pangunahing tool para sa pagtuklas ng problematikong malalakas na sanggunian sa iOS at Android.
  • Idisenyo ang graph ng pagmamay-ari nang maaga — ito ay mas mura kaysa sa pag-aayos ng pagtagas ng memorya pagkatapos ng paglabas ng application.

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.

Pag-usapan ang proyekto

Basahin din