อะไรคือความแตกต่างระหว่างการอ้างอิงที่อ่อนแอและการอ้างอิงที่ไม่มีเจ้าของ


240

สวิฟท์มี:

  • การอ้างอิงที่แข็งแกร่ง
  • ข้อมูลอ้างอิงที่อ่อนแอ
  • การอ้างอิงที่ไม่เป็นเจ้าของ

การอ้างอิงที่ไม่มีเจ้าของแตกต่างจากการอ้างอิงที่อ่อนแออย่างไร

เมื่อใดจึงจะปลอดภัยที่จะใช้การอ้างอิงที่ไม่ได้เป็นเจ้าของ

การอ้างอิงที่ไม่มีเจ้าของความเสี่ยงด้านความปลอดภัยเช่นตัวชี้ห้อยใน C / C ++?


3
บทความที่ดีมากเกี่ยวกับandrewcbancroft.com/2015/05/08/…
Zeeshan

ประสบการณ์ของฉันคือการใช้unownedสำหรับคลาสที่เราควบคุมสำหรับคลาส Apple ใช้weakเพราะเราไม่สามารถรับประกันได้ว่าจะทำอะไร
onmyway133

@NoorAli หรือ "ownerBy" เนื่องจากการอ้างอิง "ไม่ได้เป็นเจ้าของ" มักจะชี้ไปที่เจ้าของ
Ian Ringrose

คำตอบ:


361

ทั้งสองweakและunownedการอ้างอิงไม่สร้างการstrongพักไว้บนออบเจ็กต์อ้างอิง (aka พวกเขาจะไม่เพิ่มจำนวนการเก็บรักษาเพื่อป้องกัน ARC จากการยกเลิกการจัดสรรคืนออบเจ็กต์อ้างอิง)

แต่ทำไมสองคำค้นหา ความแตกต่างนี้เกี่ยวข้องกับความจริงที่ว่าOptionalประเภทนั้นมีอยู่ในภาษาสวิฟท์ เรื่องราวสั้น ๆ เกี่ยวกับพวกเขา: ประเภทที่เป็นตัวเลือกมีความปลอดภัยของหน่วยความจำ (ซึ่งทำงานได้อย่างสวยงามกับกฎตัวสร้างของ Swift - ซึ่งเข้มงวดเพื่อให้ได้รับประโยชน์นี้)

การweakอ้างอิงอนุญาตให้มีความเป็นไปได้ที่จะnilเกิดขึ้น (สิ่งนี้จะเกิดขึ้นโดยอัตโนมัติเมื่อวัตถุที่ถูกอ้างอิงถูกจัดสรรคืน) ดังนั้นประเภทของทรัพย์สินของคุณจะต้องเป็นทางเลือก - ดังนั้นคุณในฐานะโปรแกรมเมอร์จะต้องตรวจสอบก่อนที่จะใช้ คอมไพเลอร์บังคับให้คุณเขียนโค้ดที่ปลอดภัยที่สุดเท่าที่จะทำได้)

การunownedอ้างอิงสันนิษฐานว่ามันจะไม่กลายเป็นnilช่วงชีวิตของมัน การอ้างอิงที่ไม่ได้เป็นเจ้าของจะต้องตั้งค่าในระหว่างการเริ่มต้น - ซึ่งหมายความว่าการอ้างอิงจะถูกกำหนดเป็นประเภทที่ไม่จำเป็นซึ่งสามารถใช้งานได้อย่างปลอดภัยโดยไม่มีการตรวจสอบ หากมีการยกเลิกการจัดสรรวัตถุอย่างใดแอพจะหยุดทำงานเมื่อมีการใช้การอ้างอิงที่ไม่ได้เป็นเจ้าของ

จากเอกสาร Apple :

ใช้การอ้างอิงที่อ่อนแอเมื่อใดก็ตามที่ถูกต้องสำหรับการอ้างอิงนั้นที่จะกลายเป็นศูนย์ ณ จุดใดช่วงหนึ่งในช่วงชีวิตของมัน ในทางกลับกันให้ใช้การอ้างอิงที่ไม่ได้เป็นเจ้าของเมื่อคุณรู้ว่าการอ้างอิงนั้นจะไม่เป็นศูนย์เมื่อมีการตั้งค่าในระหว่างการเริ่มต้น

ในเอกสารมีบางตัวอย่างที่หารือเกี่ยวกับการรักษารอบและวิธีการทำลายพวกเขา ตัวอย่างทั้งหมดเหล่านี้จะสกัดจากเอกสาร

ตัวอย่างของweakคำหลัก:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
}

และตอนนี้สำหรับศิลปะ ASCII บางอัน (คุณควรไปดูเอกสาร - พวกเขามีไดอะแกรมสวย ๆ ):

Person ===(strong)==> Apartment
Person <==(weak)===== Apartment

PersonและApartmentตัวอย่างที่แสดงให้เห็นว่าสถานการณ์ที่สองคุณสมบัติทั้งสองที่ได้รับอนุญาตให้เป็นศูนย์ที่มีศักยภาพที่จะทำให้เกิดวงจรการอ้างอิงที่แข็งแกร่ง สถานการณ์นี้ได้รับการแก้ไขที่ดีที่สุดด้วยการอ้างอิงที่อ่อนแอ ทั้งสองเอนทิตีสามารถดำรงอยู่ได้โดยปราศจากการพึ่งพาซึ่งกันและกัน

ตัวอย่างของunownedคำหลัก:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) { self.name = name }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}

ในตัวอย่างนี้Customerอาจจะหรืออาจไม่ได้มีCreditCardแต่CreditCard มักจะCustomerเชื่อมโยงกับ เพื่อเป็นตัวแทนนี้Customerชั้นจะมีตัวเลือกcardสถานที่ให้บริการ แต่CreditCardชั้นมีไม่เลือก (และไม่มีเจ้าของ) customerสถานที่ให้บริการ

Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard

CustomerและCreditCardตัวอย่างที่แสดงให้เห็นว่าสถานการณ์ที่หนึ่งสถานที่ให้บริการที่ได้รับอนุญาตให้เป็นศูนย์และทรัพย์สินที่ไม่สามารถเป็นศูนย์อื่นมีศักยภาพที่จะก่อให้เกิดวงจรการอ้างอิงที่แข็งแกร่ง สถานการณ์นี้ได้รับการแก้ไขที่ดีที่สุดด้วยการอ้างอิงที่ไม่ได้เป็นเจ้าของ

หมายเหตุจาก Apple:

การอ้างอิงที่อ่อนแอจะต้องประกาศเป็นตัวแปรเพื่อระบุว่าค่าของพวกเขาสามารถเปลี่ยนแปลงได้ในขณะทำงาน การอ้างอิงที่อ่อนแอไม่สามารถประกาศเป็นค่าคงที่ได้

นอกจากนี้ยังมีสถานการณ์ที่สามเมื่อคุณสมบัติทั้งสองควรมีค่าอยู่เสมอและไม่ควรมีคุณสมบัติใดเป็นศูนย์เมื่อการกำหนดค่าเริ่มต้นเสร็จสมบูรณ์

และยังมีสถานการณ์การเก็บรักษาแบบคลาสสิกเพื่อหลีกเลี่ยงเมื่อทำงานกับการปิด

สำหรับวันนี้ผมขอแนะนำให้ท่านไปที่เอกสารแอปเปิ้ลหรืออ่านหนังสือ


3
นี่เป็นเรื่องเล็กน้อย แต่ฉันพบตัวอย่างของอพาร์ทเมนท์และคนค่อนข้างสับสนซึ่งยังนำเสนอโซลูชั่นเพิ่มเติมเพื่อทำลายวงจรอ้างอิงที่แข็งแกร่ง อพาร์ทเมนต์ของบุคคลนั้นเป็นทางเลือกและสามารถเป็นศูนย์ได้เช่นเดียวกับผู้เช่าของอพาร์ทเมนท์เป็นทางเลือกและสามารถเป็นศูนย์ได้ดังนั้นคุณสมบัติทั้งสองนี้จึงสามารถกำหนดได้ว่าอ่อนแอ `` `
Justin Levi Winter

คลาสบุคคล {ชื่อให้: สตริง init (ชื่อ: สตริง) {self.name = ชื่อ} อพาร์ทเมนต์ var อ่อนแอ: อพาร์ทเม้น? } อพาร์ทเม้นท์ระดับ {แจ้งหมายเลข: เริ่มต้น Int (จำนวน: ไม่ระบุ) {self.number = หมายเลข} ผู้เช่า var อ่อนแอ: คน? }
Justin Levi Winter

3
ข้อแตกต่างระหว่างweak var Person?vs. var Person?คืออะไร
คณบดี

4
@JustinLevi หากคุณประกาศคุณสมบัติทั้งสองแบบอ่อนจะมีการยกเลิกการจัดสรร บุคคลเก็บการอ้างอิงที่แข็งแกร่งกับอพาร์ทเมนท์ดังนั้นอพาร์ทเมนท์จะไม่ถูกจัดสรรคืน ถ้าอพาร์ทเม้นท์มีการอ้างอิงที่แข็งแกร่งต่อบุคคลคนนั้นพวกเขาจะสร้างวงจรการเก็บรักษา - ซึ่งสามารถถูกทำลายโดยโปรแกรมเมอร์ตอนรันไทม์ถ้าเขารู้เกี่ยวกับมัน แต่อย่างอื่นมันก็แค่หน่วยความจำรั่ว นี่คือความยุ่งยากทั้งหมดเกี่ยวกับการจัดการหน่วยความจำที่อ่อนแออ่อนแอและไม่เป็นเจ้าของในระดับที่สูงขึ้นเนื่องจาก ARC ทำสิ่งสกปรกทั้งหมดสำหรับเรา การหลีกเลี่ยงการรักษารอบเป็นหน้าที่ของเรา
Ilea Cristian

1
ประโยชน์เพียงอย่างเดียวของการไม่ได้เป็นเจ้าของเหนือความอ่อนแอคือคุณไม่จำเป็นต้องแกะและสามารถใช้ค่าคงที่ได้หรือไม่? มีอินสแตนซ์ใดบ้างที่คุณไม่สามารถใช้จุดอ่อนและสามารถใช้เป็นเจ้าของเท่านั้น
อลัน

29

ไตรมาสที่ 1 “ การอ้างอิงที่ไม่มีเจ้าของ” แตกต่างจาก“ การอ้างอิงที่อ่อนแอ” อย่างไร

ข้อมูลอ้างอิงที่อ่อนแอ:

การอ้างอิงที่อ่อนแอคือการอ้างอิงที่ไม่ได้เก็บรักษาไว้อย่างแน่นหนาในอินสแตนซ์ที่อ้างถึงและไม่หยุด ARC จากการกำจัดอินสแตนซ์ที่อ้างอิง เนื่องจากการอ้างอิงที่อ่อนแอได้รับอนุญาตให้มี“ ไม่มีค่า” คุณต้องประกาศการอ้างอิงที่อ่อนแอทุกครั้งว่ามีประเภทที่เป็นตัวเลือก (เอกสารของ Apple)

การอ้างอิงที่ไม่มีเจ้าของ:

เช่นเดียวกับการอ้างอิงที่ไม่รัดกุมการอ้างอิงที่ไม่ได้เป็นเจ้าของจะไม่ได้รับการยึดอย่างแน่นหนาในอินสแตนซ์ที่อ้างถึง อย่างไรก็ตามการอ้างอิงที่ไม่มีเจ้าของจะถือว่ามีค่าอยู่เสมอ ด้วยเหตุนี้การอ้างอิงที่ไม่เป็นเจ้าของจึงถูกกำหนดให้เป็นประเภทที่ไม่ใช่ตัวเลือกเสมอ (เอกสารของ Apple)

ควรใช้เมื่อใด:

ใช้การอ้างอิงที่อ่อนแอเมื่อใดก็ตามที่ถูกต้องสำหรับการอ้างอิงนั้นเพื่อกลายเป็นศูนย์ ณ จุดใดช่วงหนึ่งในช่วงชีวิตของมัน ในทางกลับกันให้ใช้การอ้างอิงที่ไม่ได้เป็นเจ้าของเมื่อคุณรู้ว่าการอ้างอิงนั้นจะไม่เป็นศูนย์เมื่อมีการตั้งค่าในระหว่างการเริ่มต้น (เอกสารของ Apple)


ไตรมาสที่ 2 เมื่อใดจึงจะปลอดภัยที่จะใช้ "การอ้างอิงที่ไม่ได้เป็นเจ้าของ"?

ตามที่อ้างถึงข้างต้นการอ้างอิงที่ไม่เป็นเจ้าของจะถือว่ามีค่าอยู่เสมอ ดังนั้นคุณควรใช้เฉพาะเมื่อคุณแน่ใจว่าข้อมูลอ้างอิงจะไม่เป็นศูนย์ Apple Docs แสดงตัวอย่างการใช้งานสำหรับการอ้างอิงที่ไม่ได้เป็นเจ้าของผ่านตัวอย่างต่อไปนี้

สมมติว่าเรามีสองชั้นและCustomer CreditCardลูกค้าสามารถอยู่ได้โดยไม่มีบัตรเครดิต แต่บัตรเครดิตจะไม่มีอยู่หากไม่มีลูกค้านั่นคือสามารถสันนิษฐานได้ว่าบัตรเครดิตจะมีลูกค้าอยู่เสมอ ดังนั้นพวกเขาควรมีความสัมพันธ์ต่อไปนี้:

class Customer {
    var card: CreditCard?
}

class CreditCard {
    unowned let customer: Customer
}

ไตรมาสที่ 3 อ้างอิง“ การอ้างอิงที่ไม่มีเจ้าของ” ความเสี่ยงด้านความปลอดภัยเช่น“ dangling pointers” ใน C / C ++

ฉันไม่คิดอย่างนั้น

เนื่องจากการอ้างอิงที่ไม่มีเจ้าของนั้นเป็นเพียงการอ้างอิงที่อ่อนแอซึ่งรับประกันว่าจะมีค่าดังนั้นจึงไม่ควรเสี่ยงด้านความปลอดภัย แต่อย่างใด อย่างไรก็ตามหากคุณพยายามเข้าถึงการอ้างอิงที่ไม่ได้เป็นเจ้าของหลังจากอินสแตนซ์นั้นการอ้างอิงถูกยกเลิกการจัดสรรคุณจะทริกเกอร์ข้อผิดพลาดรันไทม์และแอปจะหยุดทำงาน

นั่นเป็นความเสี่ยงเดียวที่ฉันเห็น

ลิงก์ไปยัง Apple Docs


โปรแกรมตัวอย่าง Q2 ของคุณเข้าใจง่ายเกี่ยวกับเจ้าของ. ขอขอบคุณ .. คุณสามารถเพิ่มตัวอย่างประเภทเดียวกันสำหรับผู้อ่อนแอและแข็งแกร่ง ..
Ranjith Kumar

ยอดเยี่ยม ขอบคุณ.
Swifty McSwifterton

คุณสามารถใส่ตัวอย่างทั่วไปสำหรับเจ้าของที่ไม่มีเจ้าของหรือผู้อ่อนแอได้หรือไม่?
ฮันนี่

พิจารณาวัตถุพ่อแม่และลูกถ้าลูกไม่สามารถอยู่ได้โดยไม่มีผู้ปกครองแล้วใช้unownedสำหรับทรัพย์สินของผู้ปกครองในระดับเด็ก อ่อนแอคือคีมจับในทางกลับกัน คำอธิบายที่ดี @myxtic! unownedการอ้างอิงเป็นเพียงweakการอ้างอิงที่รับประกันว่าจะมีค่า!
Saif

26

ถ้าตัวเองอาจจะเป็นศูนย์ในการใช้งานปิด[อ่อนแอตนเอง]

ถ้าตัวเองไม่เคยจะเป็นศูนย์ในการใช้งานปิด[ไม่มีเจ้าของตัวเอง]

หากการหยุดทำงานเมื่อคุณใช้[ตัวตนที่ไม่มีชื่อ]ตัวตนนั้นอาจเป็นศูนย์ในบางช่วงเวลาของการปิดนั้นและคุณอาจต้องใช้[ตัวอ่อนแอ]แทน

ดูตัวอย่างเกี่ยวกับการใช้ที่แข็งแกร่ง , อ่อนแอและไม่มีเจ้าของในการปิด:

https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html


7
ทำไมไม่เพียงแค่ใช้ความอ่อนแอถึงแม้ว่าตัวเองจะไม่มีวันเป็นศูนย์ไม่มีอันตรายใด ๆ ที่ถูกต้อง?
Boon

4
สวัสดี @Boon - นั่นเป็นคำถามที่สำคัญอย่างยิ่ง
Fattie

[ตัวเองอ่อนแอ] => ถ้าฉันใช้การปิดด้านใน viewDidLoad () จะselfเป็นศูนย์ได้อย่างไร?
Hassan Tareq

@HassanTareq ฉันคิดว่ามีตัวอย่างที่ดีสองตัวอย่างที่ถูกอ้างถึงในบทความที่กล่าวถึงข้างต้น ตรวจสอบหัวข้อ "การแก้ไขรอบการอ้างอิงที่แข็งแกร่งเพื่อการปิด", esp. ข้อความอ้างอิง: "Swift ต้องการให้คุณเขียน self.someProperty หรือ self.someMethod () (แทนที่จะเป็นเพียง someProperty หรือ someMethod ()) เมื่อใดก็ตามที่คุณอ้างถึงสมาชิกของตัวเองภายในการปิดซึ่งจะช่วยให้คุณจำได้ว่าเป็นไปได้ในการจับตัวเองโดย อุบัติเหตุ." ข้อความที่ตัดตอนมาจาก: Apple Inc. “ ภาษา Swift Programming (Swift 4)” iBooks. itunes.apple.com/de/book/the-swift-programming-language-swift-4/ ...... "
นิคเอนติน

1
@Boon หากคุณใช้อ่อนตัวแปลจะบังคับให้ตรวจสอบตัวเลือกก่อนใช้งาน ในกรณีที่คุณไม่ได้ใส่เช็คนั้นจะทำให้เกิดข้อผิดพลาดในเวลารวบรวม ไม่มีอันตรายใด ๆ
Vikas Mishra

5

สารสกัดจากลิงค์

คะแนนสรุปไม่กี่

  • เมื่อต้องการตรวจสอบว่าคุณจำเป็นต้องกังวลเกี่ยวกับความแข็งแกร่งอ่อนแอหรือไม่เป็นเจ้าของถาม“ ฉันกำลังจัดการกับชนิดอ้างอิง” หากคุณกำลังทำงานกับ Structs หรือ Enums, ARC ไม่ได้จัดการหน่วยความจำสำหรับประเภทเหล่านั้นและคุณไม่จำเป็นต้องกังวลเกี่ยวกับการระบุจุดอ่อนหรือไม่มีเจ้าของสำหรับค่าคงที่หรือตัวแปรเหล่านั้น
  • การอ้างอิงที่คาดเดายากเป็นสิ่งที่ดีในความสัมพันธ์แบบลำดับชั้นที่ซึ่งผู้ปกครองอ้างอิงเด็ก แต่ไม่ใช่ในทางกลับกัน ในความเป็นจริงการอ้างอิงที่แข็งแกร่งนั้นเป็นข้อมูลอ้างอิงที่มีค่ามากที่สุดเป็นส่วนใหญ่
  • เมื่อสองอินสแตนซ์เกี่ยวข้องกับอีกทางเลือกหนึ่งตรวจสอบให้แน่ใจว่าหนึ่งในอินสแตนซ์เหล่านั้นมีการอ้างอิงที่ไม่รัดกุม
  • เมื่อสองอินสแตนซ์สัมพันธ์กันในลักษณะที่อินสแตนซ์หนึ่งไม่สามารถมีอยู่ได้หากไม่มีอินสแตนซ์อื่นอินสแตนซ์ที่มีการอ้างอิงที่จำเป็นต้องเก็บการอ้างอิงที่ไม่เป็นเจ้าของกับอินสแตนซ์อื่น

1

ทั้งweakและunownedการอ้างอิงจะไม่ส่งผลกระทบต่อจำนวนการอ้างอิงของวัตถุ แต่การอ้างอิงที่อ่อนแอจะเป็นตัวเลือกเสมอนั่นคือสามารถเป็นศูนย์ได้ในขณะที่unownedการอ้างอิงไม่สามารถเป็นศูนย์ดังนั้นจะไม่มีทางเลือก เมื่อใช้การอ้างอิงที่เป็นตัวเลือกคุณจะต้องจัดการกับความเป็นไปได้ของวัตถุที่เป็นศูนย์เสมอ ในกรณีที่มีการอ้างอิงที่ไม่ได้เป็นเจ้าของคุณจะต้องตรวจสอบให้แน่ใจว่าวัตถุนั้นไม่มีวันว่างเปล่า การใช้การอ้างอิงที่ไม่ได้อ้างอิงกับออบเจ็กต์ nil จะคล้ายกับการแกะออพชั่นเสริมที่เป็นศูนย์

ที่กล่าวว่ามีความปลอดภัยในการใช้การอ้างอิงที่ไม่ได้อ้างอิงซึ่งคุณมั่นใจว่าอายุการใช้งานของวัตถุนั้นมากกว่าการอ้างอิง หากไม่ใช่กรณีนั้นจะเป็นการดีกว่าถ้าใช้การอ้างอิงแบบอ่อนแทน

สำหรับส่วนที่สามของคำถามฉันไม่คิดว่าการอ้างอิงที่ไม่มีเจ้าของจะคล้ายกับตัวชี้ห้อย เมื่อเราพูดถึงจำนวนการอ้างอิงเรามักจะอ้างถึงจำนวนการอ้างอิงที่แข็งแกร่งของวัตถุ ในทำนองเดียวกันอย่างรวดเร็วรักษานับการอ้างอิงที่ไม่เป็นเจ้าของและนับการอ้างอิงที่อ่อนแอสำหรับวัตถุ (จุดอ้างอิงที่อ่อนแอกับสิ่งที่เรียกว่า "โต๊ะข้าง" มากกว่าวัตถุตัวเอง) เมื่อจำนวนการอ้างอิงที่คาดเดายากถึงศูนย์วัตถุจะได้รับการกำหนดค่าเริ่มต้น แต่จะไม่สามารถยกเลิกการจัดสรรได้ถ้าจำนวนการอ้างอิงที่ไม่ได้เป็นเจ้าของนั้นมากกว่าศูนย์

ตอนนี้ตัวชี้ห้อยเป็นสิ่งที่ชี้ไปยังตำแหน่งหน่วยความจำที่ถูกยกเลิกการจัดสรรแล้ว แต่อย่างรวดเร็วเนื่องจากหน่วยความจำสามารถถูกจัดสรรคืนได้ตราบใดที่มีการอ้างอิงถึงวัตถุที่ไม่ได้เป็นเจ้าของมันไม่สามารถทำให้ตัวชี้ห้อย

มีบทความมากมายที่พูดถึงการจัดการหน่วยความจำที่รวดเร็วในรายละเอียดเพิ่มเติม นี่คือหนึ่ง


0

การอ้างอิงที่ไม่เป็นเจ้าของนั้นเป็นการอ้างอิงแบบอ่อนที่ใช้ในกรณีของความสัมพันธ์แบบตลอดชีพระหว่างวัตถุสองชิ้นเมื่อวัตถุหนึ่ง ๆ ควรจะเป็นเจ้าของโดยวัตถุอื่นเพียงวัตถุเดียวเท่านั้น มันเป็นวิธีในการสร้างการเชื่อมที่ไม่เปลี่ยนรูประหว่างวัตถุและคุณสมบัติอย่างใดอย่างหนึ่ง

ในตัวอย่างที่ให้ไว้ในวิดีโอ WWDC ที่รวดเร็วผู้เป็นเจ้าของบัตรเครดิตและบัตรเครดิตสามารถมีเจ้าของได้คนเดียวเท่านั้น ในบัตรเครดิตบุคคลนั้นไม่ควรเป็นทรัพย์สินทางเลือกเนื่องจากคุณไม่ต้องการให้บัตรเครดิตลอยอยู่กับเจ้าของเพียงคนเดียว คุณสามารถทำลายวงจรนี้ได้โดยทำให้คุณสมบัติของเจ้าของอ้างอิงเครดิตอ่อนแอ แต่นั่นก็ทำให้คุณต้องทำให้เป็นทางเลือกเช่นเดียวกับตัวแปร (ตรงข้ามกับค่าคงที่) การอ้างอิงที่ไม่มีเจ้าของในกรณีนี้หมายความว่าถึงแม้ว่า CreditCard จะไม่ได้ถือหุ้นในบุคคล แต่ชีวิตของมันก็ขึ้นอยู่กับมัน

class Person {
    var card: CreditCard?
}

class CreditCard {

    unowned let holder: Person

    init (holder: Person) {
        self.holder = holder
    }
}

เชื่อมโยงไปยังวิดีโอ wwdc หรือชื่อ?
Osa

-2

ใช้unownedเมื่อคุณแน่ใจว่าselfไม่สามารถnilอยู่ในจุดที่คุณเข้าถึงselfณ จุดนั้น

ตัวอย่าง (แน่นอนคุณสามารถเพิ่มเป้าหมายได้โดยตรงMyViewControllerแต่อีกครั้งเป็นตัวอย่างง่ายๆ):

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let myButton = MyButton { [unowned self] in
            print("At this point, self can NEVER be nil. You are safe to use unowned.")
            print("This is because myButton can not be referenced without/outside this instance (myViewController)")
        }
    }
}

class MyButton: UIButton {
    var clicked: (() -> ())

    init(clicked: (() -> ())) {
        self.clicked = clicked

        // We use constraints to layout the view. We don't explicitly set the frame.
        super.init(frame: .zero)

        addTarget(self, action: #selector(clicked), for: .touchUpInside)
    }

    @objc private func sendClosure() {
        clicked()
    }
}

ใช้weakเมื่อมีความเป็นไปได้selfอาจจะเป็นที่จุดที่คุณเข้าถึงnilself

ตัวอย่าง:

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        NetworkManager.sharedInstance.receivedData = { [weak self] (data) in
            print("Can you guarentee that self is always available when the network manager received data?")
            print("Nope, you can't. Network manager will be alive, regardless of this particular instance of MyViewController")
            print("You should use weak self here, since you are not sure if this instance is still alive for every")
            print("future callback of network manager")
        }
    }
}

class NetworkManager {

    static let sharedInstance = NetworkManager()

    var receivedData: ((Data) -> ())?

    private func process(_ data: Data) {
        // process the data...

        // ... eventually notify a possible listener.
        receivedData?(data)
    }
}

ข้อเสียของunowned:

  • มีประสิทธิภาพมากกว่าอ่อนแอ
  • คุณสามารถ (เช่นกันคุณถูกบังคับ) เพื่อทำเครื่องหมายอินสแตนซ์ที่ไม่เปลี่ยนรูป (ไม่ได้อีกต่อไปตั้งแต่ Swift 5.0)
  • บ่งชี้ถึงผู้อ่านรหัสของคุณ: อินสแตนซ์นี้มีความสัมพันธ์กับ X และมันไม่สามารถอยู่ได้โดยปราศจากมัน แต่ถ้า X หายไปฉันก็ไปด้วย

ข้อเสียของweak:

  • ปลอดภัยกว่าไม่เป็นเจ้าของ (เนื่องจากมันไม่ผิดพลาด)
  • สามารถสร้างความสัมพันธ์กับ X ที่ไปได้ทั้งสองทาง แต่ทั้งคู่สามารถอยู่ได้โดยปราศจากกันและกัน

weakหากคุณไม่แน่ใจว่าการใช้งาน เดี๋ยวก่อนฉันหมายถึงถามที่นี่ใน StackOverflow สิ่งที่คุณควรทำในกรณีของคุณ! ใช้ความอ่อนแอตลอดเวลาเมื่อคุณไม่ควรสับสนและตัวอ่านรหัสของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.