ในขณะที่ฉันสอนตัวเองการเขียนโปรแกรม iOS และแนวคิดหนึ่งที่ฉันคิดว่ายากมากที่จะสรุปคือการมอบหมาย มันคืออะไร? ทำไมและมีการใช้อย่างไร? ข้อดีคืออะไร การเขียนทางเทคนิคจากหนังสือที่ฉันอ่านทำให้ยากที่จะเข้าใจ
ในขณะที่ฉันสอนตัวเองการเขียนโปรแกรม iOS และแนวคิดหนึ่งที่ฉันคิดว่ายากมากที่จะสรุปคือการมอบหมาย มันคืออะไร? ทำไมและมีการใช้อย่างไร? ข้อดีคืออะไร การเขียนทางเทคนิคจากหนังสือที่ฉันอ่านทำให้ยากที่จะเข้าใจ
คำตอบ:
เพื่อให้เข้าใจถึงคุณต้องเข้าใจdelegates
protocols
A protocol
เป็นเหมือนสัญญาการบริการ เมื่อวัตถุ (ส่วนใหญ่มักเป็นUIViewController
คลาสย่อย แต่ไม่เสมอไป) ลงชื่อในสัญญานั่นคือการพูดว่า "ฉันสนใจที่จะให้เหตุผลในการส่งข้อความที่คุณส่งมาให้ฉัน" นี้จะคล้ายกับNSNotificationCenter
ในเรื่องที่เกี่ยวกับการลงทะเบียนสำหรับระดับที่น่าสนใจแตกต่างกันเป็นวัตถุที่มีพนักงานผู้แทนเท่านั้นที่สามารถมีหนึ่งในช่วงเวลาที่เป็นวัตถุหลายคนสามารถลงทะเบียนสำหรับเดียวกันdelegate
NSNotification
Apple ใช้การมอบหมายอย่างแพร่หลาย แม้ว่าจะมีมากขึ้นเรื่อย ๆ คุณเห็นแอปเปิ้ลย้าย API จำนวนมากไปblocks
ที่ซึ่งคล้ายกับcallbacks
ในภาษาอื่น
ดังที่ได้กล่าวไว้การมอบหมายช่วยบำรุงรักษา MVC แม้ว่าฉันจะโต้แย้งการมอบหมายเป็นรูปแบบการออกแบบในและของตัวเอง มันช่วยแยกโมเดลออกจากคอนโทรลเลอร์ เช่นในตัวอย่างของ John Cartwright, a UITableView
รู้วิธีแสดงแถวและส่วนต่างๆ มันรู้วิธีนำมาใช้ใหม่UITableViewCells
ด้วยเหตุผลด้านประสิทธิภาพ มันรู้สิ่งอื่นทั้งหมดที่UIScrollView
รู้ แต่ก็ไม่ได้รู้ซึ่งเซลล์เพื่อการแสดงผล ไม่รู้ว่าจะเติมเซลล์เหล่านั้นด้วยอะไร มันไม่ทราบซึ่งNSIndexPath
เซลล์เพื่อนำมาใช้สำหรับการรับ นี่ควรจะเป็นงานของผู้ควบคุมต่อไป การมอบหมายช่วยให้มุมมองตารางเพื่อลดตรรกะที่ไม่ใช่มุมมองนี้ลงบนวัตถุที่ควรมีความรับผิดชอบต่อไป
ยิ่งไปกว่านั้นคุณไม่ได้ถูกล็อคเข้าร่วมตัวแทนตลอดอายุการใช้งานของวัตถุ คุณสามารถมีแหล่งข้อมูลหลายแหล่งได้อย่างง่ายดายUITableView
และสลับไปมาในเวลาทำงานตามที่ต้องการ
ดังนั้นในอีกด้านหนึ่งการมอบสิทธิ์จึงยอดเยี่ยมสำหรับการจัดหาข้อมูลและตอบสนองต่อการโต้ตอบจากวัตถุ คุณจะได้เห็นมันในจำนวนมากของการเรียน UIKit เป็นเช่นUITableView
, UIPickerView
, UICollectionView
ฯลฯ
แต่การมอบหมายยังมีประโยชน์มากเมื่อคุณต้องการส่งผ่านข้อมูลระหว่างวัตถุ คุณสามารถสร้างโพรโทคอลของคุณเองได้อย่างง่ายดายและลงทะเบียนวัตถุของคุณเองเพื่อติดตามพวกเขา นอกจากนี้วิธีการโปรโตคอลเป็น@required
ค่าเริ่มต้น แต่คุณสามารถระบุวิธีการบางอย่างที่จะ@optional
. สิ่งนี้สามารถให้ความยืดหยุ่นแก่คุณได้หากคุณต้องการ สมมติว่าคุณมีตัวควบคุมมุมมองหลักและตัวควบคุมมุมมองลูก บางทีคุณอาจกำลังใช้ API การบรรจุใหม่เพื่อทำสิ่งนี้ โดยทั่วไปถ้าคุณต้องการส่งผ่านข้อมูลจากพาเรนต์ไปยังเด็กคุณทำได้ด้วยคุณสมบัติ เสร็จสิ้น แต่ถ้าคุณต้องการส่งข้อมูลจากเด็กกลับไปที่ผู้ปกครอง? อาจมีการเปลี่ยนแปลงบางอย่างในเด็กและคุณต้องแจ้งผู้ปกครอง แน่นอนคุณสามารถทำ KVO บางอย่างในค่าที่แน่นอน แต่คุณอาจต้องการทราบเมื่อกดปุ่ม เพียงแค่สร้างโปรโตคอลใหม่ในตัวควบคุมมุมมองลูก
@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end
@interface MyChildViewController : UIViewController
@property (weak, nonatomic) id <MyChildDelegate> delegate;
@end
ใน MyChildViewController เมื่อปุ่มของคุณถูกแตะเพียงตรวจสอบว่าผู้รับมอบสิทธิ์ของคุณตอบสนองต่อข้อความมอบหมาย (ถ้าจำเป็นและผู้รับมอบสิทธิ์ของคุณไม่ได้ใช้วิธีการคุณจะผิดพลาดคุณสามารถทำวิธี@optional
ถ้าคุณต้องการ) และส่ง มัน:
- (IBAction)someButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
[self.delegate buttonWasTappedInChild:self];
}
}
จากนั้นตั้งค่าผู้รับมอบสิทธิ์ของ MyChildViewController เป็นself
และนำไปใช้- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
ในตัวควบคุมมุมมองหลักของคุณ BOOM! คุณมีข้อมูลที่ส่งผ่านจากเด็กไปยังผู้ปกครอง ความสัมพันธ์ระหว่างวัตถุทั้งสองไม่จำเป็นต้องใกล้เคียงกับพ่อแม่ / ลูกด้วยซ้ำ มันเป็นสัญญาบริการดังนั้นตราบใดที่การลงทะเบียนวัตถุถือเป็นการสิ้นสุดของการต่อรองราคาโดยใช้วิธีการที่จำเป็นคุณเป็นทอง!
หมายเหตุ:ผู้ได้รับมอบหมายควรอ่อนแอ / กำหนดคุณสมบัติมิฉะนั้นคุณจะเข้าสู่วัฏจักรการเก็บรักษาซึ่งไม่สามารถยกเลิกการจัดสรรวัตถุได้
หวังว่านี่จะช่วยได้!
ผู้รับมอบสิทธิ์เป็นวัตถุที่ใช้งานฟังก์ชั่นบางอย่างเมื่อมันไม่เหมาะสมที่จะใช้ฟังก์ชั่นเหล่านั้นบนวัตถุปกติ มันเป็นรูปแบบของการฉีดพึ่งพา
สำหรับตัวอย่างที่เป็นรูปธรรมดูโปรโตคอล UITableViewDelegate วิธีการเหล่านี้ไม่เหมาะสมสำหรับมุมมองตารางที่จะนำมาใช้โดยตรงเนื่องจากการดำเนินการสำหรับการเลือกแถวมุมมองตารางจะแตกต่างกันในแต่ละแอพและอาจอยู่ในมุมมองแต่ละตาราง ผู้รับมอบสิทธิ์มีวิธีการ-tableView:didSelectRowAtIndexPath:
เพื่อให้คุณสามารถสร้างวัตถุที่จัดการการเลือกแถวโดยไม่ต้องจัดประเภทย่อยมุมมองตารางสำหรับทุกการกระทำที่แยกต่างหากที่คุณต้องการใช้