IBOutlet ควรแข็งแรงหรืออ่อนแอภายใต้ ARC หรือไม่?


551

ฉันกำลังพัฒนาเฉพาะสำหรับ iOS 5 โดยใช้ ARC ควรIBOutletเป็นUIViews (และคลาสย่อย) เป็นstrongหรือweak?

ดังต่อไปนี้:

@property (nonatomic, weak) IBOutlet UIButton *button;

จะกำจัดสิ่งเหล่านี้ทั้งหมด:

- (void)viewDidUnload
{
    // ...
    self.button = nil;
    // ...
}

มีปัญหาในการทำเช่นนี้หรือไม่? เทมเพลตใช้strongเช่นเดียวกับคุณสมบัติที่สร้างขึ้นโดยอัตโนมัติเมื่อสร้างการเชื่อมต่อโดยตรงไปยังส่วนหัวจากตัวแก้ไข 'ตัวสร้างส่วนต่อประสาน' แต่ทำไม? การอ้างอิงUIViewControllerมีอยู่แล้วซึ่งยังคงรักษาการแสดงย่อยไว้strongview


11
เป็นบันทึกIBOutletCollection()จะต้องไม่มิฉะนั้นก็จะส่งกลับเป็นweak nil
ohho

Xcode 8.2.1 ใช้อ่อนเมื่อสร้าง IBOutlets ผ่านเครื่องมือสร้างอินเตอร์เฟส อย่างไรก็ตามคำตอบมากมายเกี่ยวกับ SO แนะนำให้ใช้ความแข็งแกร่ง
neoneye

1
@neoneye ฉันลองใช้ xcode 8.3.2 การลากจากสตอรี่บอร์ดไปยังไฟล์ที่รวดเร็วและเป็นค่าเริ่มต้นไปที่strong
CupawnTae

คำตอบ:


252

ปัจจุบันคำแนะนำวิธีปฏิบัติที่ดีที่สุดจากแอปเปิ้ลสำหรับ IBOutlets ที่จะแข็งแกร่งเว้นแต่อ่อนแอเป็นสิ่งจำเป็นเฉพาะเพื่อหลีกเลี่ยงวงจรรักษา ดังที่โยฮันเนสกล่าวถึงข้างต้นสิ่งนี้ได้รับการกล่าวถึงในเซสชั่น "Implementing UI Designs in Interface Builder" จาก WWDC 2015 ที่วิศวกรของ Apple กล่าวว่า:

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

ฉันถามเกี่ยวกับสิ่งนี้ทาง Twitter ถึงวิศวกรในทีม IB และเขายืนยันว่าstrongควรเป็นค่าเริ่มต้นและเอกสารนักพัฒนาซอฟต์แวร์กำลังได้รับการปรับปรุง

https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104


33
นี่เป็นเรื่องจริงหรือไม่หรือมีคำตอบที่ถูกต้องมากกว่า 300 ข้อขึ้นไป? ฉันสังเกตว่า InterfaceBuilder ตามค่าเริ่มต้นจะใช้จุดอ่อนเมื่อคุณกด Ctrl จากกระดานเรื่องราวไปยัง. h
Arunabh Das

4
คะแนนที่มี 400+ ถูกต้องแล้ว แต่ล้าสมัยแล้ว เนื่องจาก iOS 6 viewDidUnload ไม่ได้ถูกเรียกใช้ดังนั้นจึงไม่มีประโยชน์สำหรับการมีจุดอ่อน
kjam

7
@kjam มีประโยชน์ ก่อนอื่นคุณไม่ควรถือการอ้างอิงที่แข็งแกร่งกับสิ่งที่คุณไม่ได้สร้าง ประการที่สองประสิทธิภาพเพิ่มขึ้นเล็กน้อย อย่าละเมิดแนวปฏิบัติที่ดีที่สุดในการเขียนโปรแกรมเพียงเพราะผู้ชายบางคนแม้แต่คนที่แต่งตัวประหลาดที่ดีบอกว่านี่คือ 10 ไมโครวินาทีเร็วขึ้น เจตนาชัดเจนของรหัสอย่าพยายามเล่นคอมไพเลอร์ให้เกิดประโยชน์สูงสุด รหัสสำหรับประสิทธิภาพเมื่อมีการวัดในกรณีเฉพาะเพื่อเป็นปัญหา
Cameron Lowell Palmer

5
ให้ฉันไม่เห็นด้วยกับคุณ 'ถือการอ้างอิงที่แข็งแกร่งถึงสิ่งที่คุณไม่ได้สร้าง' เกิดขึ้นตลอดเวลาใน Objective-C นั่นเป็นเหตุผลที่มีการนับการอ้างอิงแทนที่จะเป็นเจ้าของเพียงคนเดียว คุณมีการอ้างอิงเพื่อสำรองข้อมูลคำแนะนำนี้หรือไม่? คุณช่วยกรุณาเขียนรายการประโยชน์อื่น ๆ ของร้านที่อ่อนแอได้หรือไม่?
kjam

4
นี่คือวิดีโอ WWDC ที่กล่าวถึงในคำตอบdeveloper.apple.com/videos/play/wwdc2015/407/?time=1946
petrsyn

450

คำเตือนคำตอบที่ล้าสมัย : คำตอบนี้ไม่ทันสมัยตาม WWDC 2015 สำหรับคำตอบที่ถูกต้องอ้างอิงถึงคำตอบที่ยอมรับ (Daniel Hall) ด้านบน คำตอบนี้จะอยู่เพื่อบันทึก


สรุปจากห้องสมุดนักพัฒนา :

จากมุมมองของการปฏิบัติในร้าน iOS และ OS X ควรกำหนดเป็นคุณสมบัติประกาศ โดยทั่วไปแล้ว Outlets ควรจะอ่อนแอยกเว้นของจาก File เจ้าของไปจนถึงวัตถุระดับบนสุดในไฟล์ปลายปากกา (หรือใน iOS เป็นสตอรี่บอร์ดเรื่องราว) ซึ่งควรมีความแข็งแกร่ง โดยปกติแล้วร้านค้าที่คุณสร้างจะอ่อนแอเนื่องจากค่าเริ่มต้นเนื่องจาก:

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

  • ช่องทางที่แข็งแกร่งจะถูกระบุบ่อยครั้งโดยคลาสเฟรมเวิร์ก (ตัวอย่างเช่นมุมมองเต้าเสียบของ UIViewController หรือเต้าเสียบหน้าต่างของ NSWindowController)

    @property (weak) IBOutlet MyView *viewContainerSubview;
    @property (strong) IBOutlet MyOtherClass *topLevelObject;

10
คุณได้รับลิงก์ "ห้องสมุดนักพัฒนาซอฟต์แวร์" เพื่อข้ามไปยังส่วนเฉพาะของหน้าเอกสารแอปเปิ้ลได้อย่างไร เมื่อใดก็ตามที่ฉันเชื่อมโยงไปยังแอปเปิ้ลเอกสารมันจะเชื่อมโยงไปยังด้านบนของหน้าเสมอ (แม้ว่าเนื้อหาที่น่าสนใจจะลงครึ่งหนึ่งของหน้า) ขอบคุณ
bearMountain

68
ฉันคัดลอกลิงก์จากบานหน้าต่างนำทางด้านซ้าย : D
Alexsander Akers

27
"ยกเว้นสิ่งเหล่านั้นจากเจ้าของไฟล์ไปยังวัตถุระดับบนสุดในไฟล์ปลายปากกา (หรือในฉากกระดานเรื่องราวใน iOS)" หมายถึงอะไร
Van Du Tran

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

6
ระดับสูงสุดหมายความว่าเมื่อคุณดูที่ปลายปากกาวัตถุจะปรากฏในรายการทางด้านซ้าย ไส้ปากกาเกือบทั้งหมดมี UIView อยู่ในนั้น - นี่อาจเป็นวัตถุระดับบนสุดเท่านั้น หากคุณเพิ่มรายการอื่น ๆ และพวกเขาแสดงในรายการพวกเขาเป็น "วัตถุระดับบนสุด"
David H

50

ในขณะที่เอกสารแนะนำให้ใช้weakกับคุณสมบัติสำหรับการดูย่อยตั้งแต่ iOS 6 ดูเหมือนว่าจะใช้งานได้ดีstrong(ตัวระบุความเป็นเจ้าของเริ่มต้น) แทน นั่นเกิดจากการเปลี่ยนแปลงในUIViewControllerมุมมองนั้นจะไม่ถูกยกเลิกการโหลดอีกต่อไป

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

ที่กล่าวว่าฉันขาดระหว่างการใช้งาน

@property (nonatomic, weak) IBOutlet UIButton *button;

และ

@property (nonatomic) IBOutlet UIButton *button;

ใน iOS 6 และหลัง:

  • ใช้weakอย่างชัดเจนระบุว่าตัวควบคุมไม่ต้องการเป็นเจ้าของปุ่ม

  • แต่การละเว้นweakจะไม่เจ็บใน iOS 6 โดยไม่ดูจากการโหลดและสั้นกว่า บางคนอาจชี้ให้เห็นว่ายังเร็วกว่า แต่ฉันยังไม่เคยพบกับแอปที่ช้าเกินไปเพราะweak IBOutlets

  • การไม่ใช้weakอาจถือเป็นข้อผิดพลาด

บรรทัดล่าง: เนื่องจาก iOS 6 เราไม่สามารถทำสิ่งนี้ผิดได้อีกต่อไปตราบใดที่เราไม่ใช้มุมมองในการขนถ่าย เวลาไปงานเลี้ยง ;)


นั่นเป็นเรื่องจริง แต่คุณอาจต้องการยกเลิกการโหลดมุมมองด้วยตนเอง ในกรณีนี้คุณจะต้องตั้งค่าร้านค้าทั้งหมดของคุณnilด้วยตนเอง
hypercrypt

PS: weakค่อนข้างถูกกว่าใน ARM64: D
hypercrypt

ถูกต้องถ้าคุณใช้มุมมองการขนถ่ายweakคุณสมบัติหรือ__weakตัวแปรอินสแตนซ์เป็นวิธีที่จะไป ฉันแค่อยากจะชี้ให้เห็นว่ามีข้อผิดพลาดน้อยลงที่นี่ สำหรับweakราคาที่ถูกกว่าบน arm64 ฉันไม่เคยเห็นปัญหาการใช้งานจริงweak IBOutletของ s บน armv7 :)
Tammo Freese

ในกรณีนี้ก็strongสมเหตุสมผลเช่นกัน strongจะเป็นอันตรายถ้าคุณใช้มุมมองการขนถ่าย - แต่วันนี้ใคร :)
Tammo Freese

2
@Rocotilos iPhone เครื่องแรกมี RAM จำกัด มาก ถ้าฉันจำได้ถูกต้อง 128 MB เหลือประมาณ 10 MB สำหรับแอปที่ใช้งานอยู่ การมีหน่วยความจำขนาดเล็กเป็นสิ่งสำคัญดังนั้นจึงมีมุมมองที่ไม่โหลด สิ่งนี้เปลี่ยนไปเนื่องจากตอนนี้เรามี RAM มากขึ้นเรื่อย ๆ และ Apple เพิ่มประสิทธิภาพ UIViews ใน iOS 6 ดังนั้นเพื่อเตือนหน่วยความจำคุณสามารถเพิ่มหน่วยความจำจำนวนมากได้โดยไม่ต้องถอดมุมมองออก
Tammo Freese

34

ฉันไม่เห็นปัญหาใด ๆ พรี - อาร์คฉันทำ IBOutlets ของฉันเสมอassignเพราะพวกเขาดูแลโดยผู้ดูแล ถ้าคุณสร้างมันweakขึ้นมาคุณไม่ควรลบมันออกใน viewDidUnload ตามที่คุณชี้

ข้อแม้หนึ่ง: คุณสามารถรองรับ iOS 4.x ในโครงการ ARC แต่ถ้าคุณทำคุณไม่สามารถใช้งานได้weakดังนั้นคุณต้องทำให้พวกเขาassignซึ่งในกรณีนี้คุณยังคงต้องการที่จะอ้างอิงศูนย์viewDidUnloadเพื่อหลีกเลี่ยง ตัวชี้ห้อย นี่คือตัวอย่างของข้อผิดพลาดตัวชี้ห้อยที่ฉันเคยพบ:

UIViewController มี UITextField สำหรับรหัสไปรษณีย์ มันใช้ CLLocationManager เพื่อย้อนกลับ geocode ที่ตั้งของผู้ใช้และตั้งรหัสไปรษณีย์ นี่คือการติดต่อกลับของผู้ได้รับมอบหมาย:

-(void)locationManager:(CLLocationManager *)manager
   didUpdateToLocation:(CLLocation *)newLocation
          fromLocation:(CLLocation *)oldLocation {
    Class geocoderClass = NSClassFromString(@"CLGeocoder");
    if (geocoderClass && IsEmpty(self.zip.text)) {
        id geocoder = [[geocoderClass alloc] init];
        [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
            if (self.zip && IsEmpty(self.zip.text)) {
                self.zip.text = [[placemarks objectAtIndex:0] postalCode];
            }
        }];    
    }
    [self.locationManager stopUpdatingLocation];
}

ฉันพบว่าหากฉันยกเลิกมุมมองนี้ในเวลาที่เหมาะสมและไม่ได้ไม่มี self.zip ในviewDidUnloadการติดต่อกลับของผู้มอบหมายอาจทำให้เกิดข้อยกเว้นการเข้าถึงที่ไม่ดีใน self.zip.text


4
นอกจากนี้ยังเป็นความเข้าใจของฉันว่าweakคุณสมบัติไม่จำเป็นต้องได้รับการ nilled viewDidUnloadใน แต่ทำไมแม่แบบของ Apple สำหรับการสร้างร้านค้ารวมถึง[self setMySubview:nil]?
Yang Meyer

3
มีกรณีของโลกแห่งความเป็นจริงที่ใช้ความแข็งแกร่ง / เก็บไว้สำหรับ IBOutlet ของคุณอาจทำให้เกิดปัญหา? หรือเป็นเพียงการเก็บสำรองซึ่งหมายถึงรูปแบบการเข้ารหัสที่ไม่ดี แต่จะไม่ส่งผลกระทบต่อโค้ดของคุณ?
Enzo Tran

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

25

IBOutletควรมีความแข็งแกร่งด้วยเหตุผลด้านประสิทธิภาพ ดูการอ้างอิงสตอรี่บอร์ด, IBOutlet ที่แข็งแกร่ง, Scene Dock ใน iOS 9

ตามที่อธิบายไว้ในย่อหน้านี้ช่องทางสู่วิวพร็อพเพอร์ตี้ของวิวคอนโทรลเลอร์อาจไม่รัดกุมเนื่องจากมุมมองย่อยเหล่านี้เป็นของออบเจ็กต์ระดับบนสุดของไฟล์ปลายปากกาอยู่แล้ว อย่างไรก็ตามเมื่อกำหนด Outlet เป็นตัวชี้ที่อ่อนแอและตั้งค่าตัวชี้ ARC จะเรียกใช้ฟังก์ชัน runtime:

id objc_storeWeak(id *object, id value);

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

void objc_destroyWeak(id * object)

จากนั้นวัตถุจะไม่ถูกลงทะเบียนและ objc_destroyWeak โทรอีกครั้ง:

objc_storeWeak(id *object, nil)

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

ในฐานะของ Xcode 7 มันแสดงให้เห็น strong

หากคุณรับชมเซสชัน WWDC 2015 407 การใช้งานการออกแบบ UI ในตัวสร้างส่วนต่อประสานจะแนะนำ (บันทึกจากhttp://asciiwwdc.com/2015/sessions/407 )

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

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

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

ดังนั้นฉันจะเลือกที่แข็งแกร่งและฉันจะคลิกเชื่อมต่อซึ่งจะสร้างเต้าเสียบของฉัน


1
คำตอบที่ยอดเยี่ยมที่อธิบายถึงเหตุผลที่แท้จริง
micnguyen

นั่นเป็นสิ่งที่ดีและทั้งหมด แต่ฉันได้เห็นการรั่วไหลมาจากตัวจดจำท่าทางที่ใช้ในกระดานเรื่องราว
thibaut noah

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

ฉันคำนวณเวลา deinit ที่อ่อนแอและแข็งแกร่งและมันก็เหมือนกันทุกประการ
touti

แต่ในกรณีที่รวดเร็ว การอ้างอิงที่อ่อนแอนั้นเร็วกว่า
thesummersign

20

ในการพัฒนาระบบ iOS การโหลด NIB นั้นแตกต่างจากการพัฒนาของ Mac เล็กน้อย

ในการพัฒนา Mac IBOutlet มักเป็นข้อมูลอ้างอิงที่อ่อนแอ: ถ้าคุณมี subclass ของ NSViewController เฉพาะมุมมองระดับบนสุดเท่านั้นที่จะถูกเก็บไว้และเมื่อคุณ dealloc ตัวควบคุมการดูย่อยและร้านค้าทั้งหมดจะถูกปล่อยโดยอัตโนมัติ

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

ในบทความนี้จาก Big Nerd Ranchพวกเขาครอบคลุมหัวข้อนี้และอธิบายว่าทำไมการใช้การอ้างอิงที่รัดกุมใน IBOutlet ไม่ใช่ตัวเลือกที่ดี (แม้ว่า Apple แนะนำในกรณีนี้ก็ตาม)


16
มันอธิบายได้ในปี 2009 ด้วย ARC สิ่งนี้ได้เปลี่ยนไปอย่างมาก
Dafydd Williams

1
:( ลิงก์ Big Nerd Ranch ตายแล้ว ... แต่ฉันต้องอ่านจริงๆทุกคนรู้รายละเอียดเพิ่มเติมเกี่ยวกับโพสต์นั้นดังนั้นฉันสามารถหาได้หรือไม่
Motti Shneor

@ MottiShneor ไม่ต้องกังวลมันไม่ใช่เรื่องใหญ่อะไรเพราะลิงค์นั้นใช้มาก่อน ARC และไม่เกี่ยวข้องอีกต่อไป
Sergey Grischyov

18

สิ่งหนึ่งที่ฉันต้องการชี้ให้เห็นที่นี่และนั่นคือสิ่งที่วิศวกรของ Apple ได้ระบุไว้ในวิดีโอ WWDC 2015 ของพวกเขาที่นี่:

https://developer.apple.com/videos/play/wwdc2015/407/

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

ตัวอย่างแอปเปิ้ลเพย์นี้ใช้จุดอ่อน: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DLinkLink

เช่นเดียวกับตัวอย่างรูปภาพในภาพ: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player_Player.html

ตัวอย่างเช่น Lister: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57

ตัวอย่างตำแหน่งแกนกลางเช่น: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6

เช่นเดียวกับมุมมองของตัวควบคุมตัวอย่างเช่นการแสดงตัวอย่างนี้: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5

เช่นเดียวกับตัวอย่าง HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_Attlet_ActionControl_Hand_Act_Content_Activity

ทั้งหมดได้รับการอัพเดตอย่างสมบูรณ์สำหรับ iOS 9 และทั้งหมดใช้ช่องเสียบที่อ่อนแอ จากนี้เราได้เรียนรู้ว่า A. ปัญหาไม่ง่ายอย่างที่บางคนทำออกมาได้ B. Apple เปลี่ยนความคิดของพวกเขาซ้ำ ๆ และ C. คุณสามารถใช้สิ่งที่ทำให้คุณมีความสุข :)

ขอขอบคุณเป็นพิเศษกับ Paul Hudson (ผู้เขียน www.hackingwithsift.com) ที่ให้คำอธิบายและคำอ้างอิงสำหรับคำตอบนี้

ฉันหวังว่านี่จะช่วยให้เรื่องดีขึ้นเล็กน้อย!

ดูแล.


ฉันได้ตรวจสอบปัญหานี้มาระยะหนึ่งแล้วและยังไม่พบคำตอบที่เป็นรูปธรรม เนื่องจากลิงค์ด้านบนแสดงให้เห็นว่าทั้งคู่ใช้ได้และโดยทั่วไปไปกับสิ่งที่ Xcode autosuggests
subin272

9

จากงาน WWDC 2015 มีเซสชั่นในการใช้ UI ที่ออกแบบใน Interface Builder รอบเครื่องหมาย 32min ที่เขาบอกว่าคุณมักจะต้องการที่จะทำให้คุณแข็งแกร่ง@IBOutlet


น่าสนใจ ฉันเดาว่าสิ่งนี้จะเปลี่ยนไปเมื่อมุมมองการโหลดถูกลบออกไหม
hypercrypt


5

ดูเหมือนว่ามีบางสิ่งเปลี่ยนแปลงไปในช่วงหลายปีที่ผ่านมาและตอนนี้ Apple แนะนำให้ใช้งานโดยทั่วไป หลักฐานเกี่ยวกับเซสชัน WWDC ของพวกเขาอยู่ในเซสชัน 407 - การใช้งานการออกแบบ UI ในตัวสร้างส่วนต่อประสานและเริ่มต้นที่ 32:30 บันทึกของฉันจากสิ่งที่เขาพูดคือ (เกือบถ้าไม่ตรงตามที่เขาอ้าง):

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

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

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

แก้ไข:

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


4

ฉันคิดว่าข้อมูลที่สำคัญที่สุดคือ: องค์ประกอบใน xib จะอยู่ในมุมมองย่อยโดยอัตโนมัติ บทสัมภาษณ์คือ NSArray NSArray เป็นเจ้าขององค์ประกอบ ฯลฯ มีตัวชี้ที่แข็งแกร่งกับพวกเขา ดังนั้นในกรณีส่วนใหญ่คุณไม่ต้องการสร้างตัวชี้ที่แข็งแกร่งอื่น (IBOutlet)

และด้วย ARC คุณไม่จำเป็นต้องทำอะไรเลย viewDidUnload

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