ตรวจสอบว่ามีวิธีการหรือไม่


111

มีวิธีใดบ้างที่ฉันสามารถทดสอบว่ามีวิธีการอยู่ใน Objective-C หรือไม่

ฉันพยายามเพิ่มยามเพื่อดูว่าวัตถุของฉันมีวิธีการก่อนที่จะเรียกมันหรือไม่


นอกจากนี้ยังมีคำถามว่านี่เป็นแนวทางที่ถูกต้องตั้งแต่แรกหรือไม่เนื่องจากคลาส Objective-C สามารถตอบสนองต่อตัวเลือกที่พวกเขาไม่ได้ประกาศ (ผ่าน- forwardInvocation:)
Donal Fellows

คำตอบ:



72

นอกจากนี้ยังมีอินสแตนซ์ข้อความคงที่RespondToSelector: (SEL) ตัวเลือก คุณจะเรียกสิ่งนี้ว่า

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

หรือเช่นนี้:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

สิ่งนี้อาจมีประโยชน์หากคุณต้องการเรียกตัวสร้างหนึ่งตัวหรืออีกตัวหนึ่งขึ้นอยู่กับสิ่งนี้ (ฉันหมายถึงก่อนที่จะมีอินสแตนซ์เอง)


1
instancesRespondToSelector แตกต่างจาก responseToSelector อย่างไร
CReaTuS

1
ความแตกต่างที่สำคัญคือข้อความหนึ่งเป็นข้อความอินสแตนซ์ (เพื่อทดสอบว่ามีข้อความอินสแตนซ์ที่กำหนดไว้หรือไม่) ในขณะที่อีกข้อความหนึ่งเป็นข้อความคลาส (เพื่อทดสอบว่ามีข้อความคลาสที่กำหนดหรือไม่)
Ricard Pérez del Campo

1
+1 สำหรับ [MyClass instancesRespondToSelector] ฉันต้องการมันภายในเมธอดการสร้าง init: เมื่อคลาสย่อยอาจจำเป็นต้องเรียกใช้วิธีการเริ่มต้นขั้นสูงแทนวิธีอื่น ๆ (วิธีที่เลิกใช้แล้ว) เนื่องจากยังไม่ได้สร้างตัวเองและ responseToSelector จะส่งคืน NO เสมอ
LightMan

12

ใช้respondsToSelector:. จากเอกสารประกอบ :

responseToSelector:

ส่งคืนค่าบูลีนที่ระบุว่าผู้รับดำเนินการหรือสืบทอดวิธีการที่สามารถตอบสนองต่อข้อความที่ระบุ

- (BOOL)respondsToSelector:(SEL)aSelector

พารามิเตอร์
aSelector - ตัวเลือกที่ระบุข้อความ

คืนค่า
YESถ้าการดำเนินการรับหรือสืบทอดวิธีการที่สามารถตอบสนองต่อการaSelectorNOมิฉะนั้น


10

คุณกำลังมองหาresponseToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

ในฐานะที่เป็นDonal กล่าวข้างต้นจะบอกคุณว่า foo สามารถแน่นอนจัดการที่ได้รับแถบตัวเลือก อย่างไรก็ตามหาก foo เป็นพร็อกซีที่ส่งต่อแถบไปยังอ็อบเจ็กต์พื้นฐานบางอย่างที่จะรับข้อความ bar ดังนั้น responseToSelector: จะบอกคุณว่า NO แม้ว่าข้อความจะถูกส่งต่อไปยังอ็อบเจ็กต์ที่ตอบสนองต่อบาร์


1

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

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