การมอบหมายคืออะไรและทำไมจึงมีความสำคัญในการเขียนโปรแกรม iOS


11

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


4
คุณอาจพบว่าวัตถุประสงค์ c + ผู้รับมอบสิทธิ์การแยกแท็กในกองมากเกินไปมีประโยชน์

คำตอบ:


16

เพื่อให้เข้าใจถึงคุณต้องเข้าใจdelegatesprotocols

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

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! คุณมีข้อมูลที่ส่งผ่านจากเด็กไปยังผู้ปกครอง ความสัมพันธ์ระหว่างวัตถุทั้งสองไม่จำเป็นต้องใกล้เคียงกับพ่อแม่ / ลูกด้วยซ้ำ มันเป็นสัญญาบริการดังนั้นตราบใดที่การลงทะเบียนวัตถุถือเป็นการสิ้นสุดของการต่อรองราคาโดยใช้วิธีการที่จำเป็นคุณเป็นทอง!

หมายเหตุ:ผู้ได้รับมอบหมายควรอ่อนแอ / กำหนดคุณสมบัติมิฉะนั้นคุณจะเข้าสู่วัฏจักรการเก็บรักษาซึ่งไม่สามารถยกเลิกการจัดสรรวัตถุได้

หวังว่านี่จะช่วยได้!


2

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

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

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