วัตถุประสงค์ -C ARC: แข็งแรงเทียบกับการคงไว้และอ่อนแอเทียบกับการมอบหมาย


367

มีสองคุณลักษณะการจัดการหน่วยความจำใหม่สำหรับคุณสมบัตินำโดย ARC มีและstrongweak

นอกเหนือจากcopyสิ่งที่เห็นได้ชัดว่าแตกต่างอย่างสิ้นเชิงมีความแตกต่างระหว่างstrongvs retainและweakvs assign?

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

ผมไม่ทราบว่าเกี่ยวกับความแตกต่างใด ๆ ระหว่างและstrongretain

มีเหตุผลใดบ้างที่ฉันควรใช้assignและretainในโครงการใหม่หรือเป็นประเภทที่ถูกคัดค้าน?


12
มีสามคุณลักษณะการจัดการหน่วยความจำใหม่สำหรับคุณสมบัตินำโดย ARC มีstrong, และweak unsafe_unretained
NJones

5
@NJones มีสองคุณลักษณะคุณสมบัติ ( weakและstrong) และ 4 รอบคัดเลือกอายุการใช้งานตัวแปร ( __strong, __weak, __unsafe_unretained, __autoreleasing) ดู ARC Notes ด้านล่าง
Snowcrash

1
@SnowCrash มีเวอร์ชันของ Xcode ซึ่งน่าจะเป็นตัวอย่างของนักพัฒนาซึ่งการใช้assignเมื่อคอมไพล์ด้วย ARC เป็นข้อผิดพลาด มีคำตอบที่ถูกลบมากมายเกี่ยวกับเรื่องนี้ ดูเหมือนว่าจะมีการเปลี่ยนแปลงก่อนที่จะปล่อยสุดท้าย unsafe_unretainedเป็นคุณลักษณะที่ต้องการสำหรับผู้ใช้งานยุคแรกของเราหลายคน สำหรับการพิสูจน์ว่าunsafe_unretainedเป็นแอตทริบิวต์ที่ถูกต้องให้ดูที่ "การเขียนโปรแกรมด้วย Objective-C" ของ Apple ภายใต้หัวข้อ "Encapsulating Data" ภายใต้หัวข้อย่อย "ใช้ Unsafe Unretained Reference for some Classes" ซึ่งกล่าวว่า: "สำหรับคุณสมบัตินี้หมายถึงการใช้แอตทริบิวต์ unsafe_unretained:"
NJones

คำตอบ:


230

จากการเปลี่ยนเป็นบันทึกประจำรุ่น ARC (ตัวอย่างในส่วนของคุณสมบัติของคุณสมบัติ)

// The following declaration is a synonym for: @property(retain) MyClass *myObject;

@property(strong) MyClass *myObject;

ดังนั้นstrongเป็นเช่นเดียวกับretainในการประกาศทรัพย์สิน

สำหรับโครงการ ARC ที่ฉันจะใช้strongแทนretainฉันจะใช้assignสำหรับคุณสมบัติดั้งเดิมของ C และweakสำหรับการอ้างอิงที่อ่อนแอไปยังวัตถุ Objective-C


11
ในความเป็นจริงภายใต้ ARC มันเป็นข้อผิดพลาดในการรวบรวมเพื่อใช้assignสำหรับวัตถุ คุณต้องใช้อย่างใดอย่างหนึ่งweakหรือunsafe_unretained(ซึ่งไม่ปลอดภัยแน่นอน) ถ้าคุณไม่ต้องการที่จะรักษาทรัพย์สิน
cobbal

5
assignคอมไพล์ใช้ได้สำหรับฉันในโครงการ ARC ด้วยเป้าหมายการปรับใช้ 4.0
Pascal

8
@Pascal: การอ้างอิงที่อ่อนแอไม่ได้รับอนุญาตในเป้าหมายการปรับใช้ที่ระบบปฏิบัติการไม่ใช่ 5.0 หรือสูงกว่า ดังนั้นสำหรับโครงการรุ่นเก่าคุณยังสามารถใช้กำหนดได้ แต่ถ้าคุณย้ายไปใช้เวอร์ชันที่ใหม่กว่าคุณต้องเปลี่ยนเป็นอ่อนแอ
Mattia

1
หน้าตาเหมือน Xcode 4 (กับ ARC) สร้างNSManagedObject subclasses ใช้กับretain strongฉันคิดว่ามันไม่เป็นอันตราย แต่ฉันคิดว่ามันควรจะเป็นความstrongสอดคล้อง ... หรือบางทีมันอาจไม่สำคัญ stackoverflow.com/questions/7796476/…
Joe D'Andrea

3
@ JeremyP ใช่คำตอบของคุณตรงประเด็น ฉันกำลังโต้ตอบกับ @Mattia ฉันกำลังชี้ให้เห็นว่าassignยังคงใช้ได้ในบางกรณี
Steven Oxley

606

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

  1. อะตอม // ค่าเริ่มต้น
  2. nonatomic
  3. strong = รักษา // เริ่มต้น
  4. อ่อนแอ
  5. รักษา
  6. กำหนด // เริ่มต้น
  7. unsafe_unretained
  8. สำเนา
  9. อ่านเท่านั้น
  10. readwrite // ค่าเริ่มต้น

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

คุณสมบัติของตัวแปรหรือตัวดัดแปลงใน iOS

1. ที่แข็งแกร่ง (iOS4 = รักษา)

  • มันบอกว่า "เก็บสิ่งนี้ไว้ในกองจนกว่าฉันจะไม่ชี้อีกต่อไป"
  • ในคำอื่น ๆ "ฉันเป็นเจ้าของคุณไม่สามารถ dealloc นี้ก่อนที่จะปรับให้ดีกับที่เก็บ"
  • คุณใช้ความแข็งแกร่งเฉพาะในกรณีที่คุณต้องการเก็บรักษาวัตถุ
  • โดยค่าเริ่มต้นตัวแปรอินสแตนซ์ทั้งหมดและตัวแปรโลคัลเป็นตัวชี้ที่แข็งแกร่ง
  • โดยทั่วไปเราใช้ strong สำหรับ UIViewControllers (ผู้ปกครองรายการ UI)
  • strong ใช้กับ ARC และโดยพื้นฐานแล้วจะช่วยให้คุณโดยไม่ต้องกังวลเกี่ยวกับจำนวนการเก็บรักษาของวัตถุ ARC จะปล่อยให้คุณโดยอัตโนมัติเมื่อคุณใช้งานเสร็จการใช้คีย์เวิร์ด strong หมายความว่าคุณเป็นเจ้าของวัตถุ

ตัวอย่าง:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

2. อ่อนแอ -

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

ตัวอย่าง:

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

@synthesize myButton;

คำอธิบายที่แข็งแกร่งและอ่อนแอขอขอบคุณ BJ Homer :

ลองนึกภาพวัตถุของเราคือสุนัขและสุนัขต้องการที่จะวิ่งหนี (ถูกจัดสรรคืน)

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

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

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

เมื่อเราใช้อ่อน

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

3. รับ = strong

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

ตัวอย่าง:

@property (nonatomic, retain) NSString *name;

@synthesize name;

4.assign

  • กำหนดเป็นค่าเริ่มต้นและเพียงแค่ทำการกำหนดตัวแปร
  • assign เป็นคุณสมบัติคุณสมบัติที่บอกคอมไพเลอร์วิธีการสังเคราะห์การใช้งานตัวตั้งค่าของคุณสมบัติ
  • ฉันจะใช้กำหนดให้กับคุณสมบัติดั้งเดิม C และอ่อนแอสำหรับการอ้างอิงที่อ่อนแอไปยังวัตถุ Objective-C

ตัวอย่าง:

@property (nonatomic, assign) NSString *address;

@synthesize address;

5
2. "การอ้างอิงที่อ่อนแอคือการอ้างอิงที่ไม่ได้ป้องกันวัตถุที่อ้างอิงจากการรวบรวมโดยตัวเก็บขยะ" - ไม่มีสิ่งนั้นในวัตถุประสงค์ c เป็นตัวเก็บขยะ
bucherland

1
และลำดับชั้นนี้จัดการโดย iOS โดยอัตโนมัติ อ่านเกี่ยวกับแนวคิด MVC ฉันหมายถึงเมื่อมีการแสดง ViewContorller iOS โหลดเป็นลำดับชั้นการดูบนหน้าจอ เมื่อ ViewController อื่นนำเสนอลำดับชั้นของมุมมองแรกนี้จะถูกจัดสรรคืน แต่ถ้าคุณมี 'ที่แข็งแกร่ง' ใน ViewController มุมมองนี้จะไม่สามารถยกเลิกการจัดสรรได้เมื่อปิดหน้าจอ ซึ่งอาจส่งผลกระทบอย่างหนักต่อหน่วยความจำอุปกรณ์และสาเหตุของการชะลอตัวของแอป (แน่นอนว่าอุปกรณ์มีหน่วยความจำจำนวนมากและคุณจะไม่
ติดขัด

1
เมื่อเราใช้อ่อน 1. สำหรับวัตถุ UI ผู้ได้รับมอบหมาย 3. บล็อก (ควรใช้ softSelf แทนตัวเองเพื่อหลีกเลี่ยงวงจรหน่วยความจำ (ดังที่ได้กล่าวไว้แล้ว)
bucherland

1
มีข้อผิดพลาดอย่างหนึ่งในคำตอบที่ดีนี้ - แข็งแรง - "ARC จะปล่อยให้คุณโดยอัตโนมัติเมื่อคุณทำเสร็จ" นี่ไม่ถูกต้อง ARC จะปล่อยวัตถุอ่อนแอโดยอัตโนมัติเมื่อไม่มีตัวชี้ Strong - เป็นไวพจน์เพื่อเก็บรักษาดังนั้นวัตถุจะถูกเก็บไว้และเป็นความรับผิดชอบของเราที่จะทำให้วัตถุเป็นศูนย์
Ashwin G

1
@RDC defaultหมายถึงอะไร ถ้าฉันใช้@property (nonatomic) NSString *stringมันคือstrongอะไร? หรือassign? เพราะทั้งคู่เป็นค่าเริ่มต้น
Iulian Onofrei

40

nonatomic / อะตอม

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

/ strong อ่อนแอ / กำหนด

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

(ไม่จำเป็น)

สำเนา

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

อ่านเท่านั้น

  • ใช้เพื่อปิดการตั้งค่าคุณสมบัติ (ป้องกันโค้ดจากการรวบรวมหากมีการละเมิด)
  • คุณสามารถเปลี่ยนแปลงสิ่งที่ส่งมอบโดย getter โดยการเปลี่ยนตัวแปรโดยตรงผ่านตัวแปรอินสแตนซ์หรือภายในวิธี getter เอง

@ Sakthimuthiah ถูกต้องคุณต้องแก้ไขคำตอบของคุณ
Adela Toderici

@ Sakthimuthiah ไม่ถูกต้อง (และใครก็ตามที่บอกว่าเป็น) อะตอมไม่ได้ทำให้เธรดปลอดภัยแม้ว่ามันสามารถเข้าใจผิดได้ง่ายเนื่องจากพฤติกรรมของมัน โปรดอ่าน: stackoverflow.com/questions/12347236/…
Chris J

39

เท่าที่ผมรู้strongและretainเป็นคำพ้องความหมายเพื่อให้พวกเขาทำตรงเดียวกัน

จากนั้นก็weakเป็นเหมือนassignแต่ตั้งค่าโดยอัตโนมัติหลังจากที่ศูนย์วัตถุก็จะชี้ไปที่จะ deallocated

นั่นหมายความว่าคุณสามารถแทนที่ได้

แต่มีกรณีพิเศษหนึ่งที่ฉันได้พบที่ฉันต้องใช้มากกว่าassign weakสมมติว่าเรามีสองคุณสมบัติและdelegateAssign delegateWeakในทั้งสองถูกเก็บรักษาตัวแทนของเราที่เป็นเจ้าของเราโดยมีการอ้างอิงที่แข็งแกร่งเท่านั้น ผู้รับมอบสิทธิ์ถูกยกเลิกการจัดสรรดังนั้น-deallocวิธีการของเราก็ถูกเรียกเช่นกัน

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething];
    [delegateAssign doSomething];
}

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

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething]; // Does nothing, already nil.
    [delegateAssign doSomething]; // Successful call.
}

มันค่อนข้างพิเศษ แต่มันแสดงให้เราเห็นว่าweakตัวแปรเหล่านั้นทำงานอย่างไรและเมื่อมันถูกทำให้ว่างเปล่า



20

เอกสารของ Clang เกี่ยวกับการนับการอ้างอิงอัตโนมัติ Objective-C (ARC)อธิบายตัวระบุความเป็นเจ้าของและตัวดัดแปลงอย่างชัดเจน:

มีสี่คุณสมบัติการเป็นเจ้าของ:

  • __ autoreleasing
  • __ แข็งแกร่ง
  • __ * * * * * * * * unsafe_unretained
  • __ อ่อนแอ

ชนิดที่เป็นเจ้าของ nontrivially ผ่านการรับรองถ้ามันเป็นคุณสมบัติที่มี __ autoreleasing __ แข็งแกร่งหรือ __ อ่อนแอ

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

  • มอบหมายหมายถึง __ * unsafe_unretained * ความเป็นเจ้าของ
  • การทำสำเนาหมายถึง __ ความเป็นเจ้าของที่แข็งแกร่งรวมถึงพฤติกรรมปกติของซีแมนทิกต์สำเนาใน setter
  • รักษาหมายถึงการเป็นเจ้าของ__ แข็งแกร่ง
  • แข็งแกร่งหมายถึงการเป็นเจ้าของ__ แข็งแกร่ง
  • * unsafe_unretained * แสดงถึงความเป็นเจ้าของ __ * unsafe_unretained *
  • อ่อนแอหมายถึง __ ความเป็นเจ้าของที่อ่อนแอ

ด้วยข้อยกเว้นที่อ่อนแอตัวดัดแปลงเหล่านี้จะพร้อมใช้งานในโหมดที่ไม่ใช่ ARC

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

การมอบหมายเกิดขึ้นเมื่อประเมินผู้ประกอบการที่ได้รับมอบหมาย ความหมายแตกต่างกันไปตามคุณสมบัติ:

  • สำหรับวัตถุที่แข็งแกร่ง __ ผู้รับใหม่จะถูกเก็บไว้ก่อน ประการที่สอง lvalue เต็มไปด้วยความหมายดั้งเดิม; สาม Pointee ใหม่จะถูกเก็บไว้ใน lvalue ด้วยความหมายดั้งเดิม และในที่สุดปวงเก่าจะถูกปล่อยออกมา สิ่งนี้ไม่ได้ดำเนินการทางอะตอม ต้องใช้การซิงโครไนซ์ภายนอกเพื่อทำให้เกิดความปลอดภัยเมื่อเผชิญกับโหลดและร้านค้าพร้อมกัน
  • สำหรับวัตถุที่อ่อน __ lvalue จะได้รับการปรับปรุงให้ชี้ไปที่ pointee ใหม่ยกเว้นว่า pointee ใหม่นั้นเป็นวัตถุที่อยู่ระหว่างการจัดสรรคืนซึ่งในกรณีนี้ lvalue จะได้รับการอัพเดตเป็นตัวชี้ null สิ่งนี้จะต้องดำเนินการแบบอะตอมเกี่ยวกับการมอบหมายอื่น ๆ ไปยังวัตถุเพื่ออ่านจากวัตถุและเพื่อการเปิดตัวใหม่ของ pointee ใหม่
  • สำหรับอ็อบเจ็กต์ __ * unsafe_unretained * พ้อยต์ใหม่จะถูกเก็บไว้ใน lvalue โดยใช้ซีแมนทิกส์ดั้งเดิม
  • สำหรับ __ วัตถุautoreleasing , pointee ใหม่จะถูกเก็บไว้, autorelosed และถูกเก็บไว้ใน lvalue โดยใช้ semantics ดั้งเดิม

ความแตกต่างอื่น ๆ ใน Reading Init, การทำลายและการย้ายโปรดดูมาตรา 4.2 ความหมายในเอกสาร


6

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

 -(void)displayLocalVariable
  {
     NSString myName = @"ABC";
     NSLog(@"My name is = %@", myName);
  }

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

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

@interface LoginViewController ()

@property(nonatomic,strong) NSString* username;
@property(nonatomic,weak) NSString* dummyName;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

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

- (void)displayLocalVariable
{
   NSString myName = @"ABC";
   NSLog(@"My name is = %@", myName);
   self.username = myName;
}

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


@end

ตอนนี้ในโค้ดด้านบนคุณสามารถดู myName ได้รับการกำหนดให้กับ self.username และ self.username กำลังมีการอ้างอิงที่แข็งแกร่ง (ตามที่เราประกาศในส่วนติดต่อโดยใช้ @ คุณสมบัติ) เพื่อ myName (ทางอ้อมมันมีการอ้างอิงที่แข็งแกร่งกับสตริง "ABC") ดังนั้น String myName จะไม่ถูกยกเลิกการจัดสรรจากหน่วยความจำจนกระทั่งชื่อผู้ใช้ยังมีชีวิตอยู่

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

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

-(void)displayLocalVariable
  {
     NSString myName = @"ABC";
     NSLog(@"My name is = %@", myName);
     self.dummyName = myName;
  }

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

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

-(void)displayLocalVariable
      {
         NSString myName = @"ABC";
         NSLog(@"My name is = %@", myName);
         self.username = myName;
         self.dummyName = myName;
      } 

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

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

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


2

ที่แข็งแกร่ง:

  • คุณสมบัติจะไม่ทำลาย แต่เมื่อคุณตั้งค่าคุณสมบัติเป็นศูนย์วัตถุจะถูกทำลาย
  • โดยค่าเริ่มต้นตัวแปรอินสแตนซ์ทั้งหมดและตัวแปรโลคัลเป็นตัวชี้ที่แข็งแกร่ง
  • คุณใช้ความแข็งแกร่งเฉพาะในกรณีที่คุณต้องการเก็บรักษาวัตถุ
  • โดยทั่วไปเราใช้ strong สำหรับ UIViewControllers (ผู้ปกครองรายการ UI)
  • IOS 4 (ไม่ใช่ ARC) เราสามารถใช้ Retain KeyWord
  • IOS 5 (ARC) เราสามารถใช้คำหลักที่แข็งแกร่ง

ตัวอย่าง: @property (strong, nonatomic) ViewController * viewController;

@Synthesize viewController;

อ่อนแอ

โดยค่าเริ่มต้นรับโดยอัตโนมัติและตั้งค่าเป็นศูนย์

  • โดยทั่วไปเราใช้อ่อนสำหรับ IBOutlets (Childs ของ UIViewController) และผู้รับมอบสิทธิ์
  • เช่นเดียวกับการมอบหมายไม่มีการเก็บรักษาหรือปล่อย

ตัวอย่าง: @property (อ่อนแอ, ไม่ใช่เชิงอะตอม) IBOutlet UIButton * myButton;

@synthesize myButton;


1

ความแตกต่างระหว่างที่แข็งแกร่งและรักษา:

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

ความแตกต่างระหว่างอ่อนแอและมอบหมาย:

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