Weak Reference — ano ito, syntax at paggamit sa mobile development

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

Weak Reference (mahinang referensya) — ay isang referensya sa isang object na hindi nagpapataas ng retain count nito sa ARC. Ayon sa Apple Swift Language Guide, 2026, ang weak na referensya ay idinedeklara gamit ang keyword na weak at laging may opsyonal na uri. Kapag ang object ay pinalaya, lahat ng weak referensya dito ay awtomatikong nakatakda sa nil, na pumipigil sa dangling pointers at ginagawang ligtas na mekanismo ang mahinang referensya para sa pagputol ng retain cycle.

Pangunahin

  • Weak Reference — referensya na hindi nakakaapekto sa retain count ng object; kapag pinalaya ang object ay nagiging zero
  • Deklarasyon — keyword na weak bago ang var; uri laging opsyonal (?)
  • Paggamit — delegado, closure, parent-child relasyon para sa pagputol ng retain cycle
  • Kaligtasan — awtomatikong pagtakda sa nil pagkatapos ng dealokasyon ng object (zeroing weak)
  • Pagkakaiba sa unowned — weak ay nagiging zero at ligtas, unowned ay hindi nagiging zero at nangangailangan ng garantiya ng buhay

Ano ang Weak Reference?

Weak Reference — ay isang hindi nagmamay-aring referensya sa isang object sa ARC (Automatic Reference Counting). Hindi tulad ng strong referensya na nagpapataas ng retain count ng object at ginagarantiya ang buhay nito, pinapayagan ng weak referensya na palayain ang object kahit na may mga referensya pa dito. Pagkatapos palayain, ang weak referensya ay awtomatikong nakatakda sa nil — ito ay tinatawag na zeroing weak.

Zeroing weak — pangunahing tampok ng Swift at Objective-C runtime. Kapag ang referensya counter ng object ay umabot sa zero at ang object ay dinalokasyon, binibisita ng runtime ang lahat ng weak referensya sa object na ito (nakaimbak sa isang espesyal na weak table) at itinatakda ang mga ito sa nil. Ginagarantiya nito na ang pag-access sa pinalayang memorya (use-after-free) ay imposible sa pamamagitan ng weak referensya — anumang pagbasa ay nagbabalik ng nil.

Ayon sa Apple WWDC 2012 Session 406, ang zeroing weak referensya ay nag-alis ng isang buong klase ng crash bugs na nauugnay sa dangling pointers, na laganap sa manual memory management (MRR). Sa MRR ang mahinang referensya ay umiiral lamang bilang __unsafe_unretained — hindi sila nagiging zero at ang pag-access sa isang pinalayang object ay humantong sa EXC_BAD_ACCESS.

Syntax ng weak sa Swift at Objective-C

Tingnan natin ang syntax ng deklarasyon ng weak referensya sa parehong wika ng Apple ecosystem. Sa kabila ng shared runtime, ang syntax ay naiiba, ngunit ang semantika ay magkapareho.

Swift

Sa Swift ang weak referensya ay idinedeklara gamit ang keyword na weak bago ang var. Ang uri ay dapat laging opsyonal (Type?), dahil ang referensya ay maaaring maging zero anumang oras. Ang mga constant (let) ay hindi maaaring weak — mga variable lamang.

swift
class ViewController: UIViewController {
    // weak-properties: var lamang, optional lamang
    weak var delegate: ViewControllerDelegate?
    weak var parentView: UIView?

    weak var completionHandler: ((Bool) -> Void)?  // ⚠️ closure ay hindi nag-iimbak ng weak
    // ⬆️ Error: weak ay maaari lamang ilapat sa class-types, hindi sa closure
}

Mahalaga: weak ay naaangkop lamang sa mga instance ng klase (class-types), AnyObject at mga protocol na nagmamana mula sa AnyObject. Ang struct, enum at closure ay hindi maaaring weak — sila ay value type at hindi nakikilahok sa ARC.

Objective-C

Sa Objective-C ang weak properties ay idinedeklara sa pamamagitan ng attribute na __weak o modifier na weak sa property:

objective-c
// Objective-C: weak property
@interface MyViewController : UIViewController
@property (weak, nonatomic) id<MyDelegate> delegate;
@end

// Lokal na weak variable
__weak MyObject *weakRef = someStrongObject;

Ang Objective-C runtime ay nagbibigay din ng zeroing weak, ngunit karagdagang hinaharangan ang paggamit ng weak sa C-structures at ilang Core Foundation object. Para sa kanila ay ginagamit ang __unsafe_unretained — walang zeroing.

Kailan gagamit ng mahinang referensya

Mahinang referensya — hindi unibersal na solusyon, kundi kasangkapan para sa mga tiyak na sitwasyon. Ang paggamit ng weak kahit saan ay humahantong sa labis na komplikasyon at nagpapababa ng pagiging nababasa. Tingnan natin ang tamang mga sitwasyon ng paggamit.

Delegado (Delegate pattern)

Delegado — pangunahing sitwasyon para sa weak. Ang may-ari ng object (hal. UITableView) ay nagtatago ng strong referensya sa sarili nito, at ang delegado (UIViewController) ay hindi dapat magmay-ari ng table. Ginagarantiya ng Apple SDK na ang lahat ng delegate at dataSource ay weak. Para sa iyong mga protocol laging gamitin ang weak var delegate.

Parent-Child na may feedback

Kapag ang child object ay kailangang sumangguni sa magulang (hal. ChildViewController para sa access sa coordinator), gumamit ng weak referensya. Ang magulang ay nagmamay-ari ng anak (strong), ang anak ay nagmamasid sa magulang (weak) — retain cycle ay hindi kasama.

Asynchronous na closure

Capture list [weak self] — karaniwang paraan para maiwasan ang retain cycle sa closures na nakaimbak bilang properties ng klase. Kung ang self ay maaaring palayain bago matapos ang closure — weak self ay obligado.

SitwasyonWeakStrong
Delegate✅ Laging weak❌ Retain cycle
Parent → Child❌ Hindi kailangan (magulang dapat magmay-ari)✅ Strong
Child → Parent✅ Weak❌ Retain cycle
Asynchronous callback✅ [weak self]❌ Panganib retain cycle
Matibay na ugnayan (owned)❌ unowned✅ Strong

Pangkalahatang tuntunin: kung ang object A ay nagmamay-ari ng B (A → B strong), kung gayon B → A ay dapat weak o unowned. Ang direksyon ng strong referensya ay dapat laging mula sa may-ari patungo sa subordinate.

Weak vs Unowned: paghahambing at sitwasyon

Parehong weak at unowned ay hindi nagpapataas ng retain count, ngunit naiiba ang pag-uugali pagkatapos ng dealokasyon ng object. Ang pagpili sa pagitan ng mga ito ay isang usapin ng garantiya ng buhay.

Pagkakaiba

Weak: awtomatikong nagiging zero (nil), uri laging optional, nangangailangan ng unwrap bago gamitin. Ligtas — ang pag-access sa nil ay hindi nagdudulot ng crash.

Unowned: hindi nagiging zero, uri non-optional. Kung ang object ay pinalaya, ang unowned referensya ay nagiging dangling pointer — ang pag-access dito ay nagdudulot ng runtime crash. Ang unowned ay nagpapalagay na ang object ay nabubuhay nang hindi mas maikli kaysa sa nagre-referensya.

Kailan pumili ng weak

Weak piliin kung: ang object ay maaaring dinalokasyon anumang oras (delegado pagkatapos isara ang screen), hindi mo kontrolado ang buhay ng object, o nagdududa sa mga garantiya. Weak — unibersal na ligtas na pagpili.

Kailan pumili ng unowned

Unowned piliin kung: ang object ay garantisadong hindi mapapalaya nang mas maaga kaysa sa nagre-referensya (hal. Customer → CreditCard, kung saan ang card ay hindi umiiral nang walang customer). Ang unowned ay nagbibigay ng non-optional API na walang unwrap, na mas maginhawa sa code.

swift
class Order {
    let id: Int
    var items: [Item] = []

    init(id: Int) { self.id = id }

    // Matibay na ugnayan: Order ay nagmamay-ari ng Item
    func addItem(name: String) {
        let item = Item(name: name, order: self)
        items.append(item)
    }
}

class Item {
    let name: String
    unowned let order: Order          // ✅ unowned — Item ay hindi nabubuhay nang walang Order

    init(name: String, order: Order) {
        self.name = name
        self.order = order
    }
}

// Halimbawa na may weak: delegado nang walang garantiya ng buhay
protocol NetworkServiceDelegate: AnyObject {
    func didReceiveResponse(data: Data)
}

class NetworkService {
    weak var delegate: NetworkServiceDelegate?  // ✅ weak — delegado ay maaaring umalis
}

Sa halimbawa, ang Item ay gumagamit ng unowned, dahil ang elemento ng order ay hindi maaaring umiral nang walang order mismo — ang garantiya ng buhay ay bakal. Ang NetworkService ay gumagamit ng weak, dahil ang delegado (hal. ViewController) ay maaaring sarado at palayain anumang oras.

Limitasyon ng weak referensya at mga patibong

Mahinang referensya — isang malakas na kasangkapan, ngunit may mga limitasyon na mahalagang maunawaan para sa wastong paggamit sa iOS development.

Pagganap ng weak

Mahinang referensya ay mas mabagal kaysa strong: sa bawat pag-access, sinusuri ng runtime kung ang object ay pinalaya (lookup sa weak table). Sa karamihan ng mga sitwasyon ang pagkakaiba ay hindi mahahalata, ngunit sa mainit na mga loop na may milyong pag-access ang weak ay maaaring maging bottleneck. Para sa mga sitwasyong may mataas na karga gumamit ng strong at muling ayusin ang arkitektura.

Weak ay hindi naaangkop sa value type

Struct, enum, tuple — value type na hindi nakikilahok sa ARC. Ang pagtatangkang magdeklara ng weak struct ay humahantong sa error sa compilation. Para sa pag-iimbak ng mahinang referensya sa value type gumamit ng wrapper sa class-type o closure.

Weak sa multi-threading

Zeroing weak ay thread-safe: kung ang object ay pinalaya sa isang thread, ang weak referensya ay nagiging zero sa lahat ng thread nang atomic. Gayunpaman, ang agwat sa pagitan ng pagbasa ng weak referensya at paggamit nito ay maaaring humantong sa kondisyon ng karera — ang object ay pinalaya sa pagitan ng pagkuha ng weak referensya at paggamit nito. Solusyon: strong-pagkuha ng mahinang referensya sa isang lokal na variable.

swift
// Kondisyon ng karera na may weak sa multi-threading
func performAsync() {
    weak var weakSelf = self
    queue.async {
        // ⚠️ weakSelf ay maaaring nil sa pagitan ng tseke at paggamit
        if weakSelf != nil {
            weakSelf!.doSomething()  // CRASH kung naging nil
        }
    }
}

// ✅ Pag-aayos: malakas na pagkuha para sa tagal ng paggamit
func performAsyncSafe() {
    queue.async { [weak self] in
        guard let strongSelf = self else { return }
        strongSelf.doSomething()  // strongSelf — lokal na strong referensya
    }
}

Sa ligtas na variant, ang weak self ay kinukuha, pagkatapos ay agad na binubuksan sa isang lokal na strong variable na strongSelf. Kung ang self ay buhay pa — mananatiling buhay sa panahon ng pagpapatupad ng block. Kung hindi — ang guard ay nag-activate at ang code ay hindi naisasakatuparan. Ang idiom na ito — karaniwang pattern para sa asynchronous closures sa Swift.

UIView at weak outlet

IBOutlet sa Interface Builder ay dapat weak, dahil ang view hierarchy ay mayroon nang strong referensya sa subview. Ang pagdoble ng strong referensya sa controller ay hindi lumilikha ng retain cycle, ngunit labis. Ang mahinang referensya sa outlet — rekomendasyon ng Apple, kahit na maraming developer ang gumagamit ng strong para sa pagpapasimple ng code.

Mga Madalas Itanong

Maaari bang tumuro ang weak referensya sa isang object na hindi pa nagagawa?

Hindi, ang weak ay maaari lamang tumuro sa isang umiiral na object o nil. Kapag lumilikha ng bagong object, una kang makakakuha ng strong referensya (sa pamamagitan ng initializer), at pagkatapos lamang maaari kang magtalaga ng mahinang referensya. weak nil sa simula — normal na estado.

Bakit ang weak ay gumagana lamang sa class-types?

Ang Weak ay batay sa ARC na namamahala lamang ng referensya type (mga klase). Ang value type (struct, enum) ay kinokopya kapag itinalaga at walang retain count. Para sa mahinang ugnayan ng value type gumamit ng closures o wrapper sa class na may weak property.

Paano nakakaapekto ang weak sa pagganap sa loop?

Bawat pag-access sa weak referensya ay nagsasagawa ng lookup sa runtime table. Sa loop na may milyong iteration ito ay maaaring 2–5 beses na mas mabagal kaysa strong referensya. Para sa mainit na mga landas kopyahin ang weak sa lokal na strong variable bago ang loop.

Kailan maaaring maging nil ang weak referensya nang hindi inaasahan?

Kapag ang lahat ng strong referensya sa object ay nawala — sa dulo ng scope, kapag ni-reset ang property, kapag isinara ang screen. Sa multi-thread na kapaligiran ito ay maaaring mangyari sa pagitan ng dalawang linya ng code. Laging suriin ang weak sa pamamagitan ng guard let o if let.

Ano ang pagkakaiba ng weak at __weak sa Objective-C?

Semantikong magkapareho: parehong nagbibigay ng zeroing weak. Pagkakaiba: Swift ay nangangailangan ng optional type at var, Objective-C ay gumagamit ng property modifier. Objective-C rin ay sumusuporta sa __unsafe_unretained — mahinang referensya nang walang zeroing (panganib ng dangling pointer).

Buod

  • Weak Reference — hindi nagmamay-aring referensya na hindi nagpapataas ng retain count at awtomatikong nagiging zero sa dealokasyon
  • Syntaxweak var + optional type; class-types at AnyObject protocol lamang
  • Zeroing weak — runtime ay nag-zero ng lahat ng weak referensya sa pinalayang object, pumipigil sa dangling pointers
  • Sitwasyon — delegado, parent-child na may feedback, asynchronous closures ([weak self])
  • Weak vs Unowned — weak ay nagiging zero (ligtas), unowned ay hindi nagiging zero (panganib ng crash, ngunit non-optional)
  • Pagganap — weak mas mabagal kaysa strong dahil sa lookup sa runtime table; para sa mainit na mga landas kopyahin sa strong
  • Rekomendasyon — kung hindi sigurado sa garantiya ng buhay — pumili ng weak

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