ตัวเลือกใน Objective-C?


122

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

ประการที่สองถึงจุดนี้ฉันมีรหัสต่อไปนี้:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

อย่างไรก็ตามแม้ว่าthingจะเห็นได้ชัดว่าเป็น NSString ชนิดหนึ่งและควรตอบสนองต่อ lowercaseString แต่ฉันไม่สามารถรับเงื่อนไข 'responseToSelector' เพื่อส่งคืน "YES" ได้ ...


คุณต้องการที่จะอ่านคำอธิบายตัวเลือกบนเว็บไซต์ของนักพัฒนาแอปเปิ้ล: Selectors
lothar

14
หลักสูตรสแตนฟอร์ด CS193P มอบหมาย 1B? ฉันมีคำถามเดียวกันที่นี่! :)
Corstian Boerman

คำตอบ:


181

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

คุณรู้ได้อย่างไรว่าเมื่อใดควรเพิ่มลำไส้ใหญ่? คุณเพิ่มเครื่องหมายทวิภาคให้กับชื่อข้อความหากคุณจะเพิ่มโคลอนเมื่อเรียกมันซึ่งจะเกิดขึ้นหากใช้อาร์กิวเมนต์เดียว ถ้าใช้อาร์กิวเมนต์เป็นศูนย์ (ตามกรณีlowercaseString) แสดงว่าไม่มีเครื่องหมายจุดคู่ หากใช้อาร์กิวเมนต์มากกว่าหนึ่งอาร์กิวเมนต์คุณต้องเพิ่มชื่ออาร์กิวเมนต์พิเศษพร้อมกับเครื่องหมายโคลอนเช่นในcompare:options:range:locale:.

คุณยังสามารถดูเอกสารประกอบและสังเกตว่ามีหรือไม่มีเครื่องหมายโคลอนต่อท้าย


12

Selectorsเป็นวิธีที่มีประสิทธิภาพในการอ้างอิงวิธีการโดยตรงในโค้ดที่คอมไพล์ - คอมไพเลอร์คือสิ่งที่กำหนดค่าให้กับ SEL

ส่วนอื่น ๆ ได้กล่าวถึงส่วนที่สองของ q ของคุณแล้ว ':' ในตอนท้ายตรงกับลายเซ็นที่แตกต่างจากที่คุณกำลังมองหา (ในกรณีนี้ไม่มีลายเซ็น)


10

นั่นเป็นเพราะคุณต้องการไม่ได้@selector(lowercaseString) @selector(lowercaseString:)มีความแตกต่างเล็กน้อย: อันที่สองหมายถึงพารามิเตอร์ (สังเกตโคลอนที่ท้าย) แต่- [NSString lowercaseString]ไม่ได้ใช้พารามิเตอร์


5

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

SEL sel = @selector(lowercaseString);


1

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

ฉันไม่แน่ใจว่าทำไม แต่สิ่งที่ OO ทั้งหมดนี้ดูเหมือนจะเป็นของต่างประเทศสำหรับนักพัฒนา Apple ฉันขอแนะนำอย่างยิ่งให้คว้า Visual Studio Express และลองเล่นด้วย ไม่ใช่เพราะอย่างหนึ่งดีกว่าอีกวิธีหนึ่งเพียง แต่เป็นวิธีที่ดีในการพิจารณาประเด็นการออกแบบและวิธีคิด

ชอบ

introspection = reflection
+ before functions/properties = static
- = instance level

การมองปัญหาในรูปแบบต่างๆเป็นเรื่องดีเสมอและการเขียนโปรแกรมเป็นปริศนาที่ดีที่สุด


0

จากความเข้าใจของฉันเกี่ยวกับเอกสาร Apple ตัวเลือกแสดงถึงชื่อของวิธีการที่คุณต้องการโทร สิ่งที่ดีเกี่ยวกับตัวเลือกคือคุณสามารถใช้มันได้ในกรณีที่วิธีการเรียกที่แน่นอนแตกต่างกันไป ตัวอย่างง่ายๆคุณสามารถทำสิ่งต่อไปนี้

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];

0

ตามเอกสารของ apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

ตัวเลือกคือชื่อที่ใช้เพื่อเลือกวิธีการดำเนินการสำหรับอ็อบเจ็กต์หรือตัวระบุเฉพาะที่แทนที่ชื่อเมื่อคอมไพล์ซอร์สโค้ด ตัวเลือกเองไม่ได้ทำอะไรเลย เพียงแค่ระบุวิธีการ สิ่งเดียวที่ทำให้ชื่อเมธอด selector แตกต่างจากสตริงธรรมดาคือคอมไพเลอร์ต้องแน่ใจว่าตัวเลือกไม่ซ้ำกัน สิ่งที่ทำให้ตัวเลือกมีประโยชน์คือ (ร่วมกับรันไทม์) มันทำหน้าที่เหมือนตัวชี้ฟังก์ชันแบบไดนามิกที่สำหรับชื่อที่กำหนดจะชี้ไปที่การใช้งานวิธีการที่เหมาะสมกับคลาสใด ๆ โดยอัตโนมัติ สมมติว่าคุณมีตัวเลือกสำหรับการเรียกใช้เมธอดและคลาส Dog, Athlete และ ComputerSimulation (แต่ละตัวเลือกใช้เมธอดรัน)

ตัวอย่าง: เบรกพอยต์ (lldb) - set selector viewDidLoad

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

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