ความแตกต่างระหว่างข้อความและวิธีการ?


13

ใน Objective C คุณมีแนวคิดในการส่งข้อความไปยังวัตถุอื่นและสิ่งนี้คล้ายกับวิธีการโทรในภาษาเช่น C # และ Java

แต่สิ่งที่แน่นอนคือความแตกต่างที่ลึกซึ้ง? ฉันควรคิดถึงการส่งข้อความเมื่อคิดถึงรหัสของฉันอย่างไร

หมายเหตุ: เพียงแค่พื้นหลังเล็กน้อยที่นี่ฉันเป็นนักพัฒนา C # / Java ที่พยายามเข้าใจแนวคิดบางอย่างเกี่ยวกับ Objective C


2
เนื่องจากเป็นภาษาที่แตกต่างกันทั้งหมดความแตกต่างจึงไม่ลึกซึ้ง พวกมันเป็นภาษาที่แตกต่างกัน "เมื่อคิดถึงโค้ดของฉัน"? รหัสอะไร เมื่อคิดถึง Java หรือ C # คุณจะไม่คิดถึงข้อความ คุณคิดถึงวิธีการ คุณสามารถอธิบายได้ว่าภาษาที่ไม่เกี่ยวข้องกับแนวคิดที่ไม่เกี่ยวข้องสามารถมีความแตกต่าง "ที่ลึกซึ้ง" ได้อย่างไร?
S.Lott

1
โปรดถามคำถามคุณที่ stackoverflow.com
Amir Rezaei

1
คำถามนี้ควรอยู่ใน StackOverflow หรือไม่ มันเป็นคำถามเกี่ยวกับแนวคิดการเขียนโปรแกรมไม่ใช่ปัญหาเกี่ยวกับรหัสบางอย่างที่ฉันมี บางทีฉันผิดฉันไม่รู้ - ขอบเขตจะทำให้เปรอะเปื้อน ...
Vidar

1
@Vidar คำถามไม่ได้เป็นอัตนัย คุณกำลังมองหาคำนิยามในตำราเรียน โปรแกรมเมอร์เป็นมากกว่าความคิดเห็นประสบการณ์และคำถามเชิงอัตวิสัย
สตีเฟ่น Furlani

1
ตกลง - มีวิธีใดที่จะให้โมเดอเรเตอร์ย้ายคำถามนี้ไปยัง StackOverflow
Vidar

คำตอบ:


10

ข้อความคือชื่อของตัวเลือกและพารามิเตอร์สำหรับตัวเลือกนั้น

ตัวเลือกเป็นสัญลักษณ์

วิธีการคือชิ้นส่วนของรหัสในชั้นเรียนที่ระบุโดยตัวเลือก

กล่าวอีกนัยหนึ่ง[foo bar: baz]ว่า "ส่งข้อความที่เรียก@selector(bar:)พร้อมกับพารามิเตอร์bazไปยังวัตถุfooคุณสามารถส่งข้อความนั้นไปยังวัตถุต่าง ๆ มากมาย

ในทางตรงกันข้ามวิธีการ bar:ของ a Fooอาจดูเหมือน

-(int)bar:(int)n {
  return n + 1;
}

แต่สำหรับFooTwoอาจดูเหมือน

-(int)bar:(int)n {
  return n + 2;
}

(ฉันหวังว่าฉันมีไวยากรณ์ที่ถูกต้องมันไม่นานหลังจากที่ฉันได้สัมผัสกับ Objective-C)

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

สองวิธีที่มีชื่อเดียวกันและหนึ่งข้อความ

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


ดังนั้น ... ข้อความคือเมื่อคุณเรียกใช้ dispinterface (a.invoke selector, args) และวิธีการคือเมื่อคุณเรียกใช้อินเทอร์เฟซ (a.methodName)? นั่นจะไม่ทำให้ java, JavaScript, ภาษาไดนามิกทั้งหมดมีข้อความเพราะทุกอย่างเกิดขึ้นผ่านส่วนต่อประสานคู่แทนที่จะกระโดดข้ามโดยตรง
Dmitry

4

จากมุมมองทางทฤษฎีล้วนๆไม่มีความแตกต่างระหว่างทั้งสองเลย - มีหลักฐานพิสูจน์อย่างเป็นทางการจำนวนมากแสดงให้เห็นว่าทั้งสองนั้นมีความเท่าเทียมกันอย่างสมบูรณ์

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

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


3
คุณมีเอกสารอ้างอิงแสดงหลักฐานหรือไม่? ฉันอยากจะดู มีความแตกต่างอย่างมากระหว่างการเรียกใช้เมธอดของ Java และการส่งข้อความของสมอลล์ทอล์คไม่ใช่เพียงเพราะการเชื่อมโยงล่าช้า แต่ยังเนื่องมาจากการแยกการส่งและรับ: คุณไม่สามารถบอกได้ว่าตัวรับข้อความประมวลผลหรือส่งต่อข้อความ ยกตัวอย่างเช่น
Frank Shearar

@ Frankshearar: ขออภัย แต่ไม่ใช่ หลักฐานที่ฉันเห็นถูกพิมพ์และนานมาแล้วเมื่อ OOP และวิธีการใช้มันใหม่พอที่พิสูจน์เกี่ยวกับสิ่งต่าง ๆ นั้นน่าสนใจนักวิชาการ
Jerry Coffin

1

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


0

โดยปกติการเรียกเมธอดจะถูกแก้ไขในเวลาคอมไพล์ (ยกเว้นว่าคุณใช้การสะท้อนกลับใน Java) ในขณะที่ข้อความใน Objective C จะถูกส่ง ณ เวลารันไทม์


2
หากการเรียกใช้เมธอดได้รับการรวบรวมเวลาคุณไม่ได้ใช้ OOP คุณกำลังใช้น้ำตาลซินแทติกติกสำหรับฟังก์ชั่นที่มากเกินไปโดยใช้structพารามิเตอร์ตัวแรก ปลาย bindung เป็นส่วนสำคัญของความหลากหลายและดังนั้น OOP

2
ใช่. แต่ถึงกระนั้นคุณก็สามารถโค้ดวิธีการโทรกับบางสิ่ง (ใน Java) ที่รู้จักกันดีในเวลารวบรวม การโทร MyObject.foo () จะให้ข้อผิดพลาดหาก MyObject หรือ MyInterface ไม่มีเมธอด foo () ที่กำหนดไว้ ObjC จะอนุญาตให้ส่งข้อความ 'foo' ไปยังวัตถุ MyObject ของคุณและถ้า MyObject ไม่มี 'foo' สิ่งนี้จะระเบิดในเวลาทำงาน
Heiko Rupp

ฉันคิดว่า Objective C เป็นภาษาที่คอมไพล์แล้วหรือยัง?
Vidar

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

@Vidar: มันไม่ได้เป็นปัญหาของการรวบรวมกับตีความ แต่ค่อนข้างคงที่เมื่อเทียบกับแบบไดนามิก ในภาษา OOP แบบคงที่เช่น Java คอมไพเลอร์จะตรวจสอบเพื่อให้แน่ใจว่าคลาสกำหนดวิธีการในระหว่างขั้นตอนการรวบรวม ในภาษาที่พิมพ์แบบไดนามิกเช่น Objective-C ข้อความจะถูกส่งผ่านที่รันไทม์
mipadi

-1

ข้อความได้รับการจัดการโดยเคอร์เนลหรือภาษาเอง (สำหรับ ObjC เช่นมีรหัสแอสเซมบลีขนาดเล็กมากที่ทำ)

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

ความแตกต่างหลักระหว่างการเรียกเมธอดและข้อความคือ:

  • การเรียกใช้เมธอดจะเกิดขึ้นในรหัสของคุณเท่านั้น: ใน ASM จะมีการแปลโดย PUSH ของอาร์กิวเมนต์ที่ส่งผ่าน

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


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