美文网首页iOS 开发 Objective-C
OC 中的协议的一些注意点

OC 中的协议的一些注意点

作者: 望穿秋水小作坊 | 来源:发表于2021-06-24 10:42 被阅读0次

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

  • ① 构建父类
  • ② 构建协议

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

  • ① 类的属性和方法都是和这个类关联的
  • ② 协议的属性和方法不和任何类进行关联,是独立的

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

  • 要使用 respondsToSelector 进行协议检查,确保确实真的实现了该协议方法

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

  • MyView.h 代码如下
// 协议可以用来 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
  • MyView.m 代码如下

#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
  • ProtocolViewController.m 调用代码如下

#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. 思考如下问题

  • 如果把上述代码中 MyView.h 的 dataSource 改为如下声明
@property (nonatomic, weak, nullable) id dataSource;
  • 请问在 MyView.m 文件中,下面代码能编译通过吗(不考虑运行时错误)?
- (void)reload {
    [self.delegate myViewPayButtonDidClick];
}
  • 上述代码能编译通过,但是在运行时会报错
  • 按照目前的理解是类型为 id类型 的实例可以调用它能拿到的所有成员方法
  • Class 身上有同样的特质,能调用 Class 在当前上下文中访问到的所有类方法
Class myClass = nil;
[myClass canCallAllClassMethod];

相关文章

  • OC 中的协议的一些注意点

    1. 把相同的属性和方法抽取出来,有哪两种做法? ① 构建父类 ② 构建协议 2. 上述的两种做法,有什么不同? ...

  • swift4.1 系统学习十四 协议

    // 协议/*OC中也有协议,swift中的协议的作用与OC中基本一样,只是在写法上有一点区别。我们使用 prot...

  • Swift - 协议

    只能被class继承的协议 被@objc修饰的协议,还可以暴露给OC去遵守实现 可选协议 这里有个注意点,如果要使...

  • 谈谈Objective-C中的协议

    协议简述 协议(protocol)是oc中的一个重要的语言特性,协议中定义了一些方法,若某个类想要实现这个协议中的...

  • iOS编写高质量代码(四)

    协议 与 分类 协议(protocol):OC中的协议与Java里的接口(interface)类似,OC不支持多继...

  • Swift-协议

    一、概览 二、协议的定义和遵守 二、协议的继承和限定类遵守 三、方法参数要求多个协议 四、OC协议兼容 OC中协议...

  • OC协议在解耦中的应用

    OC协议在解耦中的应用 1,oc中利用协议代理解耦, delegate是OC中常用传值模式,这是一种很好的设计...

  • Swift和Object-C协议的区别

    1.OC中的协议只能用于类,swift中的协议不仅能用于类,还能用于结构体和枚举 2.OC中的协议可以设置可选实现...

  • OC和JS交互(一):协议拦截

    协议拦截 通俗点理解,就是定义好一个协议,JS使用该协议来调用OC/Swift的方法,并且传值给OC/Swift。...

  • Swift字符串

    字符串简介在OC中定义字符串 @"". Swift中用""(注意点:OC中的字符串是NSString,Swift...

网友评论

    本文标题:OC 中的协议的一些注意点

    本文链接:https://www.haomeiwen.com/subject/ccewyltx.html