เหตุใด Objective-C จึงไม่สนับสนุนวิธีการส่วนตัว


123

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

มีจำนวนของคำที่ใช้กับivars(สมาชิก) ที่ควบคุมขอบเขตของพวกเขาเช่น@private, ,@public @protectedเหตุใดจึงไม่สามารถทำได้สำหรับวิธีการเช่นกัน? ดูเหมือนว่าสิ่งที่รันไทม์ควรจะรองรับได้ มีปรัชญาพื้นฐานที่ฉันขาดหายไปหรือไม่? นี่คือเจตนา?


15
เป็นคำถามที่ดี btw
bbum

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

1
คุณไม่สามารถ "ข้ามรันไทม์" ได้ - รันไทม์คือสิ่งที่ส่งข้อความ
ชัค

"จะไม่มีวิธีใดที่วิธีส่วนตัวจะลัดวงจรการตรวจสอบนี้"คุณหมายถึง "หลีกเลี่ยง" ใช่หรือไม่ ;-)
Constantino Tsarouhas

คำตอบ:


103

คำตอบคือ ... ดี ... ง่ายๆ ความเรียบง่ายและสม่ำเสมอในความเป็นจริง

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

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

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

แก้ไข: หนึ่งในสมมติฐานที่ฉันสังเกตเห็นคือข้อความส่วนตัวจะต้องผ่านรันไทม์ซึ่งส่งผลให้ค่าใช้จ่ายสูงขึ้น นี่คือความจริงอย่างแน่นอน?

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

จะไม่มีวิธีใดที่เมธอดส่วนตัวจะลัดวงจรการตรวจสอบนี้หรือข้ามรันไทม์?

ไม่สามารถข้ามรันไทม์ได้ แต่รันไทม์ไม่จำเป็นต้องทำการตรวจสอบเมธอดส่วนตัวใด ๆ

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

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

สิ่งนี้ขยายไปไกลกว่ารันไทม์เนื่องจากมีกลไกมากมายใน Cocoa ที่สร้างขึ้นจากพลวัตที่สอดคล้องกันของ Objective-C ตัวอย่างเช่นทั้งการเข้ารหัสค่าคีย์และการสังเกตค่าคีย์อาจต้องได้รับการแก้ไขอย่างมากเพื่อรองรับเมธอดส่วนตัวซึ่งส่วนใหญ่จะเกิดจากการสร้างช่องโหว่ที่ใช้ประโยชน์ได้ไม่เช่นนั้นวิธีการส่วนตัวจะเข้ากันไม่ได้


49
+1 Objective-C คือ (ในบางแง่) เป็นภาษา "เด็กโต" ที่โปรแกรมเมอร์คาดหวังว่าจะมีระเบียบวินัยในระดับหนึ่งแทนที่จะถูกคอมไพเลอร์ / รันไทม์ตบมือทุกครั้ง ฉันพบว่ามันสดชื่น สำหรับฉันการ จำกัด การมองเห็นเมธอดระหว่างการคอมไพล์ / ลิงก์นั้นเพียงพอและดีกว่า
Quinn Taylor

11
python เพิ่มเติมคือ "obj-c-ic" :) Guido ค่อนข้างทำงานเชิงรุกในการดูแล Python บนระบบ NeXT รวมถึงการสร้าง PyObjC เวอร์ชันแรก ดังนั้น ObjC ได้อิทธิพลหลามบ้าง
bbum

3
+1 สำหรับเรื่องราวประวัติศาสตร์ที่น่าสนใจของเผด็จการผู้ใจดีเพื่อชีวิตและการข้ามผ่านของเขาด้วยระบบ NeXT ที่เป็นตำนาน
pokstad

5
ขอบคุณ. Python, Java และ Objective-C ล้วนมีโมเดลอ็อบเจ็กต์รันไทม์ที่ค่อนข้างคล้ายกับ SmallTalk [กับ SmallTalk] Java มาจาก Objective-C โดยตรง Python ใช้หลักสูตรคู่ขนานมากกว่าหนึ่งแรงบันดาลใจ แต่ Guido ศึกษา NeXTSTEP อย่างใกล้ชิด
bbum

1
ยกเว้นฉันไม่ไว้วางใจสิทธิ์การใช้งานและฉันต้องการส่งเสียงดังกับ gcc แต่เป็นก้าวแรกที่ดีอย่างแน่นอน
Cthutu

18

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

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

วิธีการส่วนตัวไม่สามารถข้ามการส่งข้อความได้ พิจารณาสถานการณ์ต่อไปนี้:

  1. คลาสAllPublicมีวิธีการอินสแตนซ์สาธารณะdoSomething

  2. คลาสอื่นHasPrivateมีวิธีการอินสแตนซ์ส่วนตัวที่เรียกว่าdoSomething

  3. คุณสร้างอาร์เรย์ที่มีจำนวนอินสแตนซ์ของทั้งสองAllPublicและHasPrivate

  4. คุณมีลูปต่อไปนี้:

    for (id anObject in myArray)
        [anObject doSomething];
    

    ถ้าคุณวิ่งห่วงจากภายในที่AllPublicรันไทม์จะต้องหยุดคุณส่งdoSomethingในHasPrivateกรณี แต่วงนี้จะสามารถใช้งานได้ถ้ามันเป็นภายในHasPrivateชั้นเรียน


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

1
ยังไม่ถึงขั้นนั้น แต่คุณอาจจะคิดถูก Objective-C มีการส่งข้อความรันไทม์เทียบกับการเรียกวิธีการรวบรวมเวลาของ C ++ ดังนั้นคุณจะพูดถึงการตรวจสอบเวลาคอมไพล์เทียบกับการตรวจสอบเวลาทำงาน
Remus Rusanu

ดูเหมือนว่าเป็นเรื่องแปลกจริงๆที่สาเหตุหลักของการไม่สนับสนุนวิธีการส่วนตัวเนื่องจากประสิทธิภาพ ฉันคิดว่า Apple ไม่ได้คิดว่าวิธีการส่วนตัวมีความจำเป็นมากไม่ว่าจะมีประสิทธิภาพหรือไม่ก็ตาม มิฉะนั้นพวกเขาควรเลือกภาษาอื่นสำหรับ บริษัท ที่มีมูลค่าหลายพันล้านดอลลาร์
pokstad

1
การเพิ่มเมธอดส่วนตัวไม่เพียง แต่ทำให้การใช้งานรันไทม์ยุ่งยาก แต่จะทำให้ความหมายของภาษาซับซ้อนขึ้น การควบคุมการเข้าถึงเป็นแนวคิดง่ายๆในภาษาคงที่ แต่เป็นการจับคู่ที่ไม่ดีสำหรับการจัดส่งแบบไดนามิกซึ่งจะมาพร้อมกับค่าใช้จ่ายเชิงแนวคิดจำนวนมากและนำไปสู่ ​​"ทำไมจึงใช้ไม่ได้" คำถาม
Jens Ayton

7
วิธีส่วนตัวจะซื้ออะไรให้คุณได้จริงเหรอ? Objective-C คือภาษาที่ใช้ C ดังนั้นหากมีใครบางคนมีโค้ดที่ทำงานอยู่ในกระบวนการของคุณพวกเขาสามารถ p0wnz กระบวนการของคุณได้อย่างง่ายดายไม่ว่า API ใด ๆ จะเป็นส่วนตัวหรือสับสนก็ตาม
bbum

13

คำตอบที่โพสต์ในตอนนี้ทำได้ดีในการตอบคำถามจากมุมมองเชิงปรัชญาดังนั้นฉันจะให้เหตุผลที่เป็นประโยชน์มากขึ้น: สิ่งที่จะได้รับจากการเปลี่ยนความหมายของภาษา? ง่ายพอที่จะ "ซ่อน" วิธีการส่วนตัวอย่างมีประสิทธิภาพ ยกตัวอย่างเช่นสมมติว่าคุณมีคลาสที่ประกาศในไฟล์ส่วนหัวดังนี้:

@interface MyObject : NSObject {}
- (void) doSomething;
@end

หากคุณต้องการวิธีการ "ส่วนตัว" คุณสามารถใส่ไว้ในไฟล์การนำไปใช้งานได้:

@interface MyObject (Private)
- (void) doSomeHelperThing;
@end

@implementation MyObject

- (void) doSomething
{
    // Do some stuff
    [self doSomeHelperThing];
    // Do some other stuff;
}

- (void) doSomeHelperThing
{
    // Do some helper stuff
}

@end

แน่นอนว่ามันไม่ได้ค่อนข้างเช่นเดียวกับวิธีเอกชน c ++ / Java แต่มันได้อย่างมีประสิทธิภาพใกล้พอเพื่อปรับเปลี่ยนความหมายของภาษาเช่นเดียวกับคอมไพเลอร์รันไทม์ ฯลฯ ทำไมการเพิ่มคุณลักษณะที่เทิดทูนอยู่แล้วในที่ยอมรับได้ วิธี? ดังที่ระบุไว้ในคำตอบอื่น ๆ ความหมายที่ส่งผ่านข้อความและการพึ่งพาการสะท้อนแบบรันไทม์จะทำให้การจัดการข้อความ "ส่วนตัว" ไม่เป็นเรื่องเล็กน้อย


1
ปัญหาของวิธีนี้คือใครบางคนสามารถลบล้างเมธอดส่วนตัว (แม้จะไม่รู้ตัว) เมื่อพวกเขาแบ่งคลาสย่อยของคุณ ฉันคิดว่าโดยพื้นฐานแล้วคุณต้องเลือกชื่อที่ไม่น่าจะถูกแทนที่
dreamlax

3
ซึ่งให้ความรู้สึกเหมือนเป็นการแฮ็คที่แฮ็ค
Rob Jones

1
@ ไมค์: แอปเปิ้ลได้กล่าวว่าชื่อวิธีด้วยขีดชั้นนำจะถูกสงวนไว้อย่างชัดเจนสำหรับแอปเปิ้ลเท่านั้น: developer.apple.com/mac/library/documentation/Cocoa/Conceptual/... ทางเลือกที่แนะนำคือการขึ้นต้นด้วยตัวพิมพ์ใหญ่สองตัวแล้วขีดล่าง
dreamlax

8
นอกจากนี้ให้โยน SSN ของคุณหลังจากวิธีการเพื่อให้โปรแกรมเมอร์คนอื่นรู้ว่าใครเป็นคนเขียน = D Namespaces ต้องการพวกเขา !!!
pokstad

2
หากคุณกังวลเกี่ยวกับวิธีการที่คุณกำหนดว่าจะถูกลบล้างคุณไม่ได้ยอมรับระดับความฟุ่มเฟื่อยโดยธรรมชาติที่ Objective-C สนับสนุนอย่างเหมาะสม ...
Kendall Helmstetter Gelner

7

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

ไม่เอะอะอะไรเลย


จำเป็นต้องกำหนดสิ่งเหล่านี้นอกส่วน @implementation หรือไม่
Rob Jones

@Rob - ไม่สามารถกำหนดได้ (และเป็นไปได้มากที่สุด) ในการใช้งานชั้นเรียนของคุณ
Cromulent

6

ใช่สามารถทำได้โดยไม่ส่งผลกระทบต่อรันไทม์โดยใช้เทคนิคที่คอมไพเลอร์ใช้สำหรับจัดการ C ++: name-mangling

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

คุณสามารถมีส่วนร่วมในแพตช์เพื่อ clang หรือ gcc ที่เพิ่มเมธอดส่วนตัวให้กับไวยากรณ์และสร้างชื่อที่แตกต่างกันซึ่งรู้จักเพียงอย่างเดียวในระหว่างการคอมไพล์ (และลืมทันที) จากนั้นคนอื่น ๆ ในชุมชน Objective-C จะสามารถตัดสินได้ว่าคุ้มค่าจริงหรือไม่ มันน่าจะเร็วกว่าการพยายามโน้มน้าวใจนักพัฒนา


2
การโกงชื่อเวลาคอมไพล์นั้นยากกว่าที่คิดเนื่องจากคุณต้องยุ่งเกี่ยวกับตัวเลือกวิธีการทั้งหมดรวมถึงตัวเลือกที่อาจปรากฏในไฟล์ XIB และสิ่งที่อาจถูกส่งไปยังสิ่งต่างๆเช่น NSSelectorFromString () รวมถึง KeyValueCoding & friends ...
bbum

1
ใช่มันจะเกี่ยวข้องมากขึ้นหากคุณต้องการให้การสนับสนุนวิธีการส่วนตัวใน toolchain ตารางสัญลักษณ์ของคอมไพเลอร์จะต้องถูกจัดเก็บและเข้าถึงได้ผ่านทาง API ของ toolchain บางตัว คงไม่ใช่ครั้งแรกที่ Apple ต้องเพิ่มขีดความสามารถให้กับนักพัฒนาที่มีความสำคัญเพียงพอตามเวลาและความเสถียรที่อนุญาต อย่างไรก็ตามในกรณีที่วิธีการส่วนตัวเกี่ยวข้อง: เป็นที่น่าสงสัยว่าเป็นการชนะที่เพียงพอหรือไม่ที่จะดำเนินการ ยิ่งต้องสงสัยว่าพวกเขาควรจะสามารถเข้าถึงได้จากภายนอกชั้นเรียนด้วยกลไกอื่น ๆ เหล่านี้
Huperniketes

1
การบังคับใช้การคอมไพล์เท่านั้นเวลาอย่างเดียว + การโกงชื่อจะหยุดคนที่เดินรายการวิธีการของชั้นเรียนและพบในนั้นได้อย่างไร
dreamlax

มันจะไม่ คำตอบของฉันตอบเฉพาะคำถามที่ตั้งโดย OP
Huperniketes

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

4

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

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


1

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

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


และหากผู้บริโภคใน lib ของคุณสามารถสะท้อนถึงวิธีการส่วนตัวของคุณได้พวกเขาจะเรียกพวกเขาด้วยไม่ได้หรือ?
Jared Updike

หากพวกเขารู้ว่าต้องดูที่ไหนผู้คนใช้ไลบรารีที่ไม่มีเอกสารบน iPhone หรือไม่? ปัญหาของ iPhone คือคุณมีความเสี่ยงที่จะไม่ยอมรับแอปของคุณสำหรับการใช้ API ส่วนตัว
pokstad

หากพวกเขาเข้าถึงวิธีการส่วนตัวผ่านการไตร่ตรองพวกเขาจะได้รับสิ่งที่สมควรได้รับ ข้อผิดพลาดใด ๆ ไม่ใช่ความผิดของคุณ
gnasher729

1

มีสองคำตอบขึ้นอยู่กับการตีความของคำถาม

ประการแรกคือการซ่อนการใช้งานวิธีการจากอินเทอร์เฟซ โดยทั่วไปจะใช้กับหมวดหมู่ที่ไม่มีชื่อ (เช่น@interface Foo()) สิ่งนี้อนุญาตให้ออบเจ็กต์ส่งข้อความเหล่านั้น แต่ไม่ใช่ของคนอื่นแม้ว่าจะยังคงลบล้างโดยไม่ได้ตั้งใจ (หรืออย่างอื่น)

คำตอบที่สองบนสมมติฐานที่ว่านี่เกี่ยวกับประสิทธิภาพและการซับในนั้นเป็นไปได้ แต่เป็นฟังก์ชัน C ในเครื่องแทน ถ้าคุณต้องการ 'foo เอกชน ( NSString *arg) วิธีการที่คุณจะทำvoid MyClass_foo(MyClass *self, NSString *arg)และเรียกว่าเป็นฟังก์ชัน C MyClass_foo(self,arg)เช่น ไวยากรณ์แตกต่างกัน แต่ทำหน้าที่กับลักษณะการทำงานที่มีเหตุผลของวิธีการส่วนตัวของ C ++

แม้ว่าสิ่งนี้จะตอบคำถาม แต่ฉันควรชี้ให้เห็นว่าหมวดหมู่ที่ไม่มีชื่อเป็นวิธี Objective-C ทั่วไปในการทำเช่นนี้


0

Objective-C ไม่สนับสนุนวิธีการส่วนตัวเนื่องจากไม่จำเป็นต้องใช้

ใน C ++ ทุกเมธอดจะต้องมองเห็นได้ในการประกาศคลาส คุณไม่สามารถมีเมธอดที่ผู้อื่นรวมทั้งไฟล์ส่วนหัวมองไม่เห็น ดังนั้นหากคุณต้องการให้เมธอดที่โค้ดนอกการนำไปใช้ไม่ควรใช้คุณไม่มีทางเลือกคอมไพลเลอร์จะต้องให้เครื่องมือบางอย่างเพื่อที่คุณจะได้บอกได้ว่าต้องไม่ใช้เมธอดนั่นคือคีย์เวิร์ด "ส่วนตัว"

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

สำหรับตัวแปรอินสแตนซ์ที่คุณเคยต้องประกาศในไฟล์ส่วนหัว (ไม่ใช่อีกต่อไป) จะมี @private, @public และ @protected


0

คำตอบที่ขาดหายไปที่นี่คือเนื่องจากวิธีการส่วนตัวเป็นความคิดที่ไม่ดีจากมุมมองของการวิวัฒนาการ อาจดูเหมือนเป็นความคิดที่ดีที่จะทำให้วิธีการเป็นส่วนตัวเมื่อเขียน แต่เป็นรูปแบบของการผูกในช่วงต้น บริบทอาจเปลี่ยนไปและผู้ใช้ในภายหลังอาจต้องการใช้การนำไปใช้งานอื่น เร้าใจเล็กน้อย: "นักพัฒนา Agile ไม่ใช้วิธีส่วนตัว"

เช่นเดียวกับ Smalltalk Objective-C สำหรับโปรแกรมเมอร์ที่โตแล้ว เราให้ความสำคัญกับการรู้ว่านักพัฒนาซอฟต์แวร์ดั้งเดิมคิดว่าอินเทอร์เฟซควรเป็นอย่างไรและรับผิดชอบในการจัดการกับผลที่ตามมาหากเราจำเป็นต้องเปลี่ยนการใช้งาน ใช่มันเป็นปรัชญาไม่ใช่การนำไปใช้


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