iOS 开发 Objective-C

OC 中的协议的一些注意点

2021-06-24  本文已影响0人  望穿秋水小作坊

1. 把相同的属性和方法抽取出来,有哪两种做法?

2. 上述的两种做法,有什么不同?

3. OC 中调用遵守协议中的方法时,为了确保安全,要怎么做?

4. 有空练习一下(就能比较彻底明白,UITableViewDelegate 和 UITableViewDataSource)

// 协议可以用来 view 显示的数据源,也可以用来 view 的代理使用,典型的例子就是 UITableView;
// 有 返回值 的作为数据源使用,没有返回值的作为 代理 使用

#import <UIKit/UIKit.h>

@protocol MyViewDataSource <NSObject>

- (NSUInteger)numbersOfPeople;
- (NSString *)titleForView;

@end

@protocol MyViewDelegate <NSObject>

- (void)myViewPayButtonDidClick;

@end

@interface MyView : UIView

@property (nonatomic, weak, nullable) id<MyViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id<MyViewDelegate> delegate;

- (void)reload;

@end

#import "MyView.h"

@interface MyView ()

@property(nonatomic, strong) UILabel *titleLabel;
@property(nonatomic, strong) UILabel *peopleLabel;

@property(nonatomic, strong) UIButton *payButton;
@end

@implementation MyView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 300, 44)];
        self.titleLabel.text = @"默认标题";
        [self addSubview:self.titleLabel];
        
        self.peopleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, 300, 44)];
        self.peopleLabel.text = @"默认人数 0";
        [self addSubview:self.peopleLabel];
        
        self.payButton = [UIButton buttonWithType:UIButtonTypeSystem];
        self.payButton.frame = CGRectMake(20, 300, 300, 44);
        [self.payButton setTitle:@"付款按钮" forState:UIControlStateNormal];
        [self addSubview:self.payButton];
        [self.payButton addTarget:self action:@selector(payButtonAction) forControlEvents:UIControlEventTouchUpInside];
        
    }
    return self;
}

- (void)reload {
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(titleForView)]) {
        self.titleLabel.text = [self.dataSource titleForView];
    }
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(numbersOfPeople)]) {
        self.peopleLabel.text = [NSString stringWithFormat:@"具体人数 %lu", (unsigned long)[self.dataSource numbersOfPeople]];
    }
}

- (void)payButtonAction {
    if ([self.delegate respondsToSelector:@selector(myViewPayButtonDidClick)]) {
        [self.delegate myViewPayButtonDidClick];
    }
}

@end

#import "ProtocolViewController.h"
#import "MyView.h"

@interface ProtocolViewController ()<MyViewDataSource, MyViewDelegate>

@property(nonatomic, strong) MyView* myView;
@property(nonatomic, assign) NSUInteger peopleCount;

@end

@implementation ProtocolViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.myView = [[MyView alloc] init];
    [self.view addSubview:self.myView];
    [self.myView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];
    self.myView.dataSource = self;
    self.myView.delegate = self;
}


- (void)myViewPayButtonDidClick {
    NSLog(@"控制器收到点击事件");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesBegan");
    [self.myView reload];
}

- (NSUInteger)numbersOfPeople {
    return ++self.peopleCount;
}

- (nonnull NSString *)titleForView {
    return @"来自控制器的标题";
}


@end

5. 思考如下问题

@property (nonatomic, weak, nullable) id dataSource;
- (void)reload {
    [self.delegate myViewPayButtonDidClick];
}
Class myClass = nil;
[myClass canCallAllClassMethod];
上一篇下一篇

猜你喜欢

热点阅读