ความแตกต่างระหว่างจุดแข็งและจุดอ่อนใน Objective-C


308

ฉันใหม่กับ Obj-C ดังนั้นคำถามแรกของฉันคือ:

อะไรคือความแตกต่างระหว่างstrongและweakใน@propertyการประกาศของพอยน์เตอร์ไปยังวัตถุ?

นอกจากนี้nonatomicหมายความว่าอย่างไร


19
จริงๆแล้วนี่เป็นคำถามที่ดีบางครั้งเราลืมว่าแนวคิดพื้นฐานของการตั้งค่าที่แข็งแกร่ง / อ่อนแอและอะตอม / nonatomic .... :) ขอบคุณที่เตือนเราเกี่ยวกับมัน ...
andikurnia

10
@ JackyBoy อะไรที่ตลกก็คือการค้นหาแบบง่าย ๆ ที่นำเสนอบน google นำฉันมาที่นี่ฮ่า ๆ #circularreference
Jason Renaldo

10
ฉันมักจะไม่ให้ความไว้วางใจหลายคำตอบใน google แต่มักจะอ้างถึงดังนั้นคำตอบที่ชาญฉลาด
JeffK

คำตอบ:


642

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

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

  1. คุณสมบัติตัวแทนซึ่งมักจะอ้างอิงอ่อนแอเพื่อหลีกเลี่ยงการรักษารอบและ

  2. หัวข้อย่อย / การควบคุมของมุมมองหลักของตัวควบคุมมุมมองเนื่องจากมุมมองเหล่านั้นถูกเก็บไว้อย่างแน่นหนาโดยมุมมองหลัก

atomic vs. nonatomic อ้างถึงความปลอดภัยของเธรดของเมธอด getter และ setter ที่คอมไพเลอร์สังเคราะห์สำหรับคุณสมบัติ atomic (ค่าเริ่มต้น) บอกคอมไพเลอร์เพื่อให้วิธีการเข้าถึงเธรดปลอดภัย (โดยการเพิ่มล็อคก่อนที่จะเข้าถึง ivar) และ nonatomic ทำตรงข้าม ข้อดีของ nonatomic คือประสิทธิภาพที่สูงขึ้นเล็กน้อย บน iOS แอปเปิลใช้ nonatomic สำหรับคุณสมบัติเกือบทั้งหมดดังนั้นคำแนะนำทั่วไปก็คือให้คุณทำเช่นเดียวกัน


28
@ Bourne: ขึ้นอยู่กับสิ่งที่คุณหมายถึงความปลอดภัยของด้าย atomicรับประกันได้ว่าคุณสมบัติสามารถอ่านและเขียนได้อย่างปลอดภัยจากหลายเธรดในเวลาเดียวกัน ไม่ได้หมายความว่าวัตถุที่มีคุณสมบัติทั้งหมดatomicจะปลอดภัยต่อเธรดโดยอัตโนมัติ
Ole Begemann

3
รายละเอียดยอดเยี่ยม ฉันคิดว่าฉันไม่ได้รับมันจนถึงตอนนี้ ขอบคุณ.
ahmedalkaff

1
ตามเอกสารของแอปเปิ้ลอะตอมและ nonatomic ควรตรงกันกับความปลอดภัยของเธรด developer.apple.com/library/ios/documentation/cocoa/conceptual/…
Murtaza Khursheed Hussain

5
"หมายเหตุ: คุณสมบัติของอะตอมมิกไม่ตรงกันกับความปลอดภัยของเธรดของวัตถุ" developer.apple.com/library/ios/documentation/cocoa/conceptual/…
GS

ทำไมเราไม่ลบอินสแตนซ์เมื่อเราไม่ต้องการ ทำไมเราไม่สามารถนำอากาศออกจากบอลลูนหรือทำลายมันเมื่อเราไม่ต้องการทำไมเราต้องใส่ใจเกี่ยวกับสายที่แนบมา? เราแค่ต้องการข้อมูล
Ashish Pisey

706

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

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

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

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


68
+2 (ถ้าฉันทำได้) คำอธิบายที่สร้างสรรค์อย่างจริงจังจริงๆ!
Con Antonakos

25
หลังจากปีที่ 1 และครึ่งหนึ่งของการพัฒนา iOS ของคุณผมคิดว่าเพียงแค่ตอนนี้ผมเข้าใจอย่างชัดเจนว่าstrongและweakจริงหมายถึง
Isuru

17
@ X.Li รอบการเก็บรักษาเป็นเหมือนคุณมี 2 สายไปยัง ballon หนึ่งในนั้นเป็นของคุณ (คุณเป็นเจ้าของ ballon นี้) อีกที่หนึ่งเป็นเจ้าของโดย ballon (ดังนั้น ballon นี้เป็นเจ้าของคุณ) เนื่องจากคุณมีสิทธิ์เข้าถึงสายของคุณเท่านั้นคุณจะปล่อยให้ลูกโป่งไปได้อย่างไรถ้าลูกโป่งไม่ต้องการไป ดังนั้นมันจะดีกว่าถ้าคุณเป็นเจ้าของ ballon (strong) ในขณะที่ ballon ไม่ได้เป็นเจ้าของคุณ (อ่อนแอ) เมื่อคุณต้องการที่จะปล่อยมันไปเพียงแค่ตัดสาย :)
354 snakeninny

5
อ่านโปรไฟล์ของเขาเขาเป็นผู้สอน iOS คำอธิบายที่สร้างสรรค์มาก !! Hats Off :)
Hemang

3
Atomic vs non-atomic ฉันคิดว่าสามารถอธิบายได้ว่าเป็นห้องส้วมสาธารณะที่มีประตูหลายบานโดยมีห้องน้ำ 1 ห้องอยู่ตรงกลาง เมื่อใครซักคนเข้าห้องน้ำผ่านประตูหนึ่งเขาอาจล็อคประตูอื่น ๆ ทั้งหมดเข้าห้องน้ำถ้าเขาไม่อยากสัมผัสกับช่วงเวลาที่น่าอึดอัดใจ ฮ่า ๆ. ขอบคุณสำหรับการอ่านเรื่องไร้สาระที่คล้ายคลึงกันนี้
เฉินหลี่หยง

24

strong : กำหนดค่าขาเข้าให้กับมันมันจะเก็บค่าขาเข้าและปล่อยค่าที่มีอยู่ของตัวแปรอินสแตนซ์

อ่อน : จะกำหนดค่าที่เข้ามาให้โดยไม่ต้องรักษามัน

ดังนั้นความแตกต่างพื้นฐานคือการรักษาตัวแปรใหม่ Generaly คุณต้องการที่จะเก็บไว้ แต่มีสถานการณ์ที่คุณไม่ต้องการที่จะมีอย่างอื่นคุณจะได้รับรอบการเก็บรักษาและไม่สามารถเพิ่มหน่วยความจำวัตถุ เช่น. obj1 ยังคง obj2 และ obj2 ยังคง obj1 เพื่อแก้ไขสถานการณ์เช่นนี้คุณใช้การอ้างอิงที่ไม่ดี


12

คำตอบหลอกตา: -

ฉันคิดว่าคำอธิบายมีให้ในคำตอบข้างต้นดังนั้นฉันแค่จะบอกคุณว่าจะใช้STRONGและสถานที่ที่จะใช้WEAK:

การใช้Weak: - 1. ผู้ได้รับมอบหมาย 2. Outlets 3. Subviews 4. การควบคุม ฯลฯ

การใช้Strong: -WEAKที่เหลืออยู่ทุกที่ซึ่งไม่ได้รวมอยู่ใน


2
และอื่น ๆ ประกอบด้วย: P
Rajneesh071

3
webView, mapView, ฯลฯ
shubham mishra

4
อันที่จริงแล้วมุมมองย่อยที่เราลากและวางลงบนกระดานเรื่องราว
shubham mishra

8

แข็งแรงและอ่อนแอคำหลักเหล่านี้หมุนรอบความเป็นเจ้าของวัตถุใน Objective-C

ความเป็นเจ้าของวัตถุคืออะไร?

ตัวแปรตัวชี้บ่งบอกถึงความเป็นเจ้าของของวัตถุที่พวกเขาชี้ไปที่

  • เมื่อเมธอด (หรือฟังก์ชัน) มีตัวแปรเฉพาะที่ชี้ไปยังวัตถุตัวแปรนั้นจะถูกกล่าวถึงว่าเป็นเจ้าของวัตถุที่ถูกชี้ไป
  • เมื่อวัตถุมีตัวแปรอินสแตนซ์ที่ชี้ไปยังวัตถุอื่นวัตถุที่มีตัวชี้จะถูกกล่าวว่าเป็นเจ้าของวัตถุที่ถูกชี้ไป

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

ตัวแปรสามารถเลือกที่จะไม่เป็นเจ้าของวัตถุที่ชี้ไป ตัวแปรที่ไม่ได้เป็นเจ้าของวัตถุเรียกว่าการอ้างอิงที่อ่อนแอ

ลองดูคำอธิบายโดยละเอียดที่นี่เข้าใจอย่างลึกซึ้ง @ คุณสมบัติและคุณสมบัติ


6

ที่นี่เอกสารของ Appleได้อธิบายความแตกต่างระหว่างคุณสมบัติที่อ่อนแอและแข็งแรงโดยใช้ตัวอย่างต่าง ๆ :

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

ที่นี่ในผู้เขียนบล็อกนี้ได้รวบรวมคุณสมบัติทั้งหมดไว้ในที่เดียวกัน มันจะช่วยในการเปรียบเทียบคุณสมบัติของคุณสมบัติ:

http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


6

strongเป็นค่าเริ่มต้น วัตถุยังคง“ มีชีวิตอยู่” ตราบใดที่ยังมีตัวชี้ที่แข็งแกร่งอยู่

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


2

เพื่อให้เข้าใจการอ้างอิงที่รัดกุมและอ่อนแอให้พิจารณาตัวอย่างด้านล่างสมมติว่าเรามีวิธีการตั้งชื่อเป็น displayLocalVariable

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

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

ทีนี้ถ้าเราต้องการเก็บตัวแปร myView ไว้ตลอดวงจรชีวิตของ view controller สำหรับสิ่งนี้เราสามารถสร้างคุณสมบัติชื่อเป็น username ซึ่งจะมีการอ้างอิงที่แข็งแกร่งกับตัวแปร myView (ดู@property(nonatomic,strong) UIView* usernameView;และself.usernameView = myView;ในรหัสด้านล่าง) ดังต่อไปนี้

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

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

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

ตอนนี้ให้พิจารณากำหนด myName ให้กับ dummyNameView ซึ่งเป็นการอ้างอิงที่อ่อนแอself.dummyNameView = myView;ซึ่งต่างจากการอ้างอิงที่แข็งแกร่ง Weak จะเก็บ myView ไว้จนกว่าจะมีการอ้างอิงที่แข็งแกร่งใน myView ดูโค้ดด้านล่างเพื่อทำความเข้าใจข้อมูลอ้างอิงที่อ่อนแอ

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

ในโค้ดด้านบนมีการอ้างอิงที่อ่อนแอไปยัง myView (เช่น self.dummyNameView มีการอ้างอิงที่อ่อนแอกับ myView) แต่ไม่มีการอ้างอิงที่แข็งแกร่งใน myView ดังนั้น self.dummyNameView จะไม่สามารถเก็บค่า myView ได้

ลองพิจารณารหัสด้านล่างอีกครั้ง

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

ในโค้ดข้างต้น self.usernameView มีการอ้างอิงที่แข็งแกร่งไปยัง myView ดังนั้น self.dummyNameView จะมีค่าของ myView แม้หลังจากที่เมธอดสิ้นสุดลงเนื่องจาก myView มีการอ้างอิงที่แข็งแกร่งที่เกี่ยวข้อง

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

หวังว่านี่จะช่วยได้


2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] ฉันชื่อ = ABC 2019-07-25 12: 33: 15.479226 และ 0530 StrongAndWeak [6329: 245483] ชื่อของฉันคือ strong = ABC 2019- 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] ชื่อของฉันคืออ่อนแอ = ABC ในที่นี้คุณบอกว่าทรัพย์สินที่อ่อนแอไม่มีคุณค่าของชื่อฉัน แต่ฉันได้รับค่าชื่อเป็น ABC สำหรับการอ้างอิงทั้งสอง .. .. คุณช่วยให้คำตอบที่ชัดเจนยิ่งขึ้นได้ไหมขอบคุณล่วงหน้า
Madhu_Nani

@Raviteja_DevObal ARC ไม่สัญญาว่าจะทำมันทันที (เช่นจัดสรรคืนสตริง @ "ABC") แต่จะได้รับการจัดสรรคืนอย่างแน่นอนในภายหลัง ...
Mahadev Mandale

@Raviteja_DevObal ตามที่อธิบายไว้ที่นี่สตริงเป็นตัวอย่างที่ไม่ดีสำหรับเรื่องนี้ ฉันได้อัปเดตคำตอบของฉันด้วยวัตถุ UIView หวังว่าจะช่วยได้
Mahadev Mandale

1

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

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

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