Protocol-プロトコルDelegate and Data Source

4339 ワード

簡単な説明:すべてコールバックで、違いはあまり大きくないようです.
  • Delegate-依頼:一般コールバックメソッド関数、will didなど
  • DataSource-データソース:一般コールバックデータ
  • しかし使用時の感覚には特に大きな違いはなく、観察システムのUItableView-DelegateとDataSource
  •  // DDelegate
        - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    
    // DataSource
        - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
        - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
    

    簡単な例Delegate
  • 1 protocolプロトコル
  • を書く
    //      
    @protocol testDelegate 
    - (void)didSelectButton:(NSInteger)index;
    @end
    
    // weak  delegate
    @interface TestDelegate : UIView
    @property (nonatomic, weak) id delegate;
    @end
    
  • 2 delegate接続
  • を使用
    
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            
            CGFloat height = CGRectGetHeight(frame) / 3;
            
            //         button。
            for (NSInteger a = 0; a < 3; a ++) {
                UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
                button.frame = CGRectMake(0, height * a, CGRectGetWidth(frame), height);
                [button addTarget:self action:@selector(testDelegateButtonAction:) forControlEvents:UIControlEventTouchUpInside];
                button.backgroundColor = [UIColor redColor];
                button.tag = 8000 + a;
                [self addSubview:button];
            }
        }
        return self;
    }
    
    //     buttons     ,  delegate   
    - (void)testDelegateButtonAction:(UIButton *)button{
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(didSelectButton:)]) {
            [self.delegate didSelectButton:button.tag - 8000];
        }
        
    }
    
  • 3 delegateコールバック
  • を使用
    //     <>
    @interface ViewController ()
    
    //    delegate = self;
        TestDelegate *testelegateView = [[TestDelegate alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        testelegateView.delegate = self;
        [self.view addSubview:testelegateView];
    
    // delegate     
    - (void)didSelectButton:(NSInteger)index{
        // do something    delegate        。
    }
    

    簡単なデータソース
    Delegateと同じ流れだと思います.
  • 1書き込みプロトコル
  • //   delegate   ,         ?
    @protocol testDataSource 
    
    //     :
    @required
    - (NSInteger)numberOfLabels;
    
    //     
    @optional
    - (NSString *)label:(UILabel *)label titleOfIndex:(NSInteger)index;
    
    @end
    
    @interface TestDataSource : UIView
    @property (nonatomic, weak) id dateSource;
    //         ,        ,     。      tableView   reloadData   UI。
    - (void)reloadData;
    @end
    
  • 2 dataSource接続
  • を使用
    - (void)reloadData{
        if (!self.dateSource) {
            return;
        }
        
        //       dataSource
        NSInteger number = [self.dateSource numberOfLabels];
        CGFloat height = CGRectGetHeight(self.bounds) / number;
        
        for (NSInteger a = 0; a < number; a ++) {
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, height * a, CGRectGetWidth(self.bounds), height)];
            [self addSubview:label];
            
            //       dataSource
            if ([self.dateSource respondsToSelector:@selector(label:titleOfIndex:)]) {
                NSString *title = [self.dateSource label:label titleOfIndex:a];
                label.text = title;
            }
        }
    }
    
  • 3 dataSourceコールバック
  • を使用
    //     <>
    @interface ViewController ()
    
    //      dataSource = self   reloadData
        TestDelegate *testelegateView = [[TestDelegate alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        testelegateView.dateSource = self;
        [self.view addSubview:testelegateView];
        [testelegateView reloadData];
    
    
    // dataSource   
    - (NSInteger)numberOfLabels{
        return 3;
    }
    - (NSString *)label:(UILabel *)label titleOfIndex:(NSInteger)index{
        NSArray *arr = @[@"1",@"2",@"3"];
        return arr[index];
    }
    

    その他
    dataSourceについてはちょっと疑問がありますが、間違っているところがあれば、指摘してほしいです.