คุณสมบัติภายใต้ ARC: เสมอหรือสาธารณะเท่านั้น


9

หลังจากอ่านบทความชื่อ"รหัสบัญญัติ: วิธีปฏิบัติที่ดีที่สุดสำหรับการเข้ารหัส Objective-C" โดย Robert McNallyน้อยกว่าสองปีที่ผ่านมาเล็กน้อยฉันยอมรับการฝึกใช้คุณสมบัติสำหรับสมาชิกข้อมูลทุกคนในคลาส Objective-C ของฉัน ( บัญญัติที่ 3 ณ เดือนพฤษภาคม 2012) McNally แสดงเหตุผลเหล่านี้ในการทำเช่นนั้น (สิ่งที่ฉันให้ความสำคัญ):

  1. คุณสมบัติบังคับใช้ข้อ จำกัด การเข้าถึง (เช่นอ่านได้อย่างเดียว)
  2. คุณสมบัติบังคับใช้นโยบายการจัดการหน่วยความจำ (แข็งแรงอ่อนแอ)
  3. คุณสมบัติให้โอกาสในการใช้ setters และ getters แบบกำหนดเองอย่างโปร่งใส
  4. คุณสมบัติที่มี setters หรือ getters แบบกำหนดเองสามารถใช้เพื่อบังคับใช้กลยุทธ์ความปลอดภัยของเธรด
  5. การมีวิธีการเข้าถึงตัวแปรอินสแตนซ์เดียวช่วยเพิ่มความสามารถในการอ่านรหัส

ฉันใส่คุณสมบัติส่วนใหญ่ของฉันในหมวดหมู่ส่วนตัวดังนั้นหมายเลข 1 และ 4 มักจะไม่ใช่ปัญหาที่ฉันเรียกใช้ ข้อโต้แย้งที่ 3 และ 5 นั้นนุ่มนวลกว่าและด้วยเครื่องมือที่เหมาะสมและความสอดคล้องอื่น ๆ พวกเขาอาจกลายเป็นไม่ใช่ประเด็นปัญหา ในที่สุดสำหรับฉันข้อโต้แย้งที่มีอิทธิพลมากที่สุดคือหมายเลข 2 การจัดการหน่วยความจำ ฉันทำสิ่งนี้มานับ แต่นั้น

@property (nonatomic, strong) id object; // Properties became my friends.

สำหรับโปรเจ็กต์สุดท้ายของฉันฉันเปลี่ยนมาใช้ ARC ซึ่งทำให้ฉันสงสัยว่าการสร้างคุณสมบัติสำหรับอะไรที่สวยมากยังคงเป็นความคิดที่ดีหรืออาจจะฟุ่มเฟือยเล็กน้อย ARC ดูแลหน่วยความจำในการจัดการออบเจกต์ Objective-C ให้ฉันซึ่งสำหรับstrongสมาชิกส่วนใหญ่จะใช้งานได้ดีถ้าคุณเพิ่งประกาศ ivars ประเภท C ที่คุณต้องจัดการด้วยตนเองก่อนและหลัง ARC และweakคุณสมบัติส่วนใหญ่เป็นสาธารณะ

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

@implementation GTWeekViewController
{
    UILongPressGestureRecognizer *_pressRecognizer;
    GTPagingGestureRecognizer *_pagingRecognizer;
    UITapGestureRecognizer *_tapRecognizer;
}

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

  1. ข้อกำหนดของรหัสข้อมูลสมาชิก ( @property/ @synthesize) ย่อลงเหลือเพียงการประกาศ ivar
  2. ส่วนใหญ่เป็นของการอ้างอิงการทำความสะอาดขึ้นเพียงself.something_something
  3. สามารถแยกแยะได้อย่างง่ายดายว่าสมาชิกข้อมูลใดเป็นส่วนตัว (ivars) และเป็นสาธารณะ (คุณสมบัติ)
  4. ท้ายที่สุดมัน 'รู้สึก' มากกว่านี้คือจุดประสงค์ที่แอปเปิลตั้งใจให้ แต่มันเป็นการคาดเดาแบบอัตนัย

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

แก้ไข: McNally ชั่งน้ำหนักใน Twitter พูดว่า : "ฉันคิดว่าเหตุผลหลักของฉันในการผสานกับคุณสมบัติคือ: วิธีหนึ่งที่จะทำทุกอย่างซึ่งทำทุกอย่าง (รวมถึง KVC / KVO)"

คำตอบ:


5

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

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

  1. การประกาศ @property ค่อนข้างคล้ายกับการประกาศ ivar การหลีกเลี่ยงคำสั่ง @synthesize ดูเหมือนจะไม่ชนะอย่างยิ่งใหญ่ - เราไม่ได้พูดถึงโค้ดจำนวนมาก

  2. foo.somethingไวยากรณ์เป็น arguably _somethingมากดีกว่า ไวยากรณ์การเข้าถึงคุณสมบัติถูกออกแบบมาให้มีลักษณะเหมือนและทำงานเหมือนกับจุดไวยากรณ์ของ C สำหรับการเข้าถึงสมาชิกของโครงสร้าง ชัดเจนว่าคุณกำลังเข้าถึงวัตถุใด (ไม่ว่าจะเป็นselfอย่างอื่นหรืออย่างอื่น) มีประโยชน์ (บางคน - ไม่ใช่ฉัน! - สนับสนุนself->somethingการเข้าถึง ivar ด้วยเหตุผลนี้) การประชุมขีดเส้นใต้ที่เป็นผู้นำสำหรับ ivars นั้นใช้ได้ แต่ไม่ได้ใช้อย่างสม่ำเสมอโดยรหัส Objective-C ทั้งหมด

  3. คุณสมบัติดูเหมือนเป็นทางเลือกที่ดีกว่าสำหรับการเข้าถึงข้อมูลที่เก็บไว้ในวัตถุอื่นของคลาสเดียวกัน (ซึ่งได้รับอนุญาตภายใต้การเข้าถึงแบบ "ส่วนตัว") และสำหรับการเข้าถึงโดยคลาสย่อย (เช่น "การป้องกัน" ของ C ++) ดังนั้นความคิด 'คุณสมบัติ == สาธารณะ' จึงค่อนข้างพร่ามัว

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

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

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


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

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

-1

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


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