美文网首页知识点
iOS的扩展&代理&通知

iOS的扩展&代理&通知

作者: 宋唐不送糖 | 来源:发表于2021-07-23 08:30 被阅读0次

    扩展(Extension)

    一般用扩展来做什么?

    1.声明私有属性,是可以不对子类暴露的。
    2.声明私有方法,方便阅读。
    3.声明私有成员变量

    扩展的特点:

    1.编译时决议。
    2.只以声明的形式存在,没有具体实现,多数情况寄生于宿主类的.m中,也就是说,它不是独立存在实现的一个文件,可以把扩展理解为类的一个内部的私有声明。
    3.不能为系统类添加扩展。

    分类和扩展的区别:

    1.分类是运行时决议,扩展是编译时决议。
    2.分类可以有声明有实现,而扩展只有声明,它的实现是直接写在宿主类当中。
    3.可以为系统类添加分类,但不能为系统类添加扩展。

    代理(Delegate):

    什么是代理:

    1.准确的说是一种软件设计模式,代理模式.
    2.iOS当中以@protocol形式体现.
    3.传递方式是一对一.
    代理的工作流程:


    1.委托方会要求代理放需要实现的接口,全部定义在协议当中。
    2.在协议当中可以声明属性,也可以声明方法。
    3.代理会按照协议实现方法。
    4.代理会返回一个处理结果给委托方。
    5.委托方需要调用代理方遵从的协议方法。

    首先定义一个协议类,来定义公共协议

    #import <Foundation/Foundation.h>
    @protocol LoginProtocol <NSObject>
    @optional
    - (void)userLoginWithUsername:(NSString *)username password:(NSString *)password;
    @end
    

    定义委托类,这里简单实现了一个用户登录功能,将用户登录后的账号密码传递出去,由代理来处理具体登录细节。

    #import <UIKit/UIKit.h>
    #import "LoginProtocol.h"
    /**
     *  当前类是委托类。用户登录后,让代理对象去实现登录的具体细节,委托类不需要知道其中实现的具体细节。
     */
    @interface LoginViewController : UIViewController
    // 通过属性来设置代理对象
    @property (nonatomic, weak) id<LoginProtocol> delegate;
    @end
     
    实现部分:
     
    @implementation LoginViewController
    - (void)loginButtonClick:(UIButton *)button {
      // 判断代理对象是否实现这个方法,没有实现会导致崩溃
      if ([self.delegate respondsToSelector:@selector(userLoginWithUsername:password:)]) {
          // 调用代理对象的登录方法,代理对象去实现登录方法
          [self.delegate userLoginWithUsername:self.username.text password:self.password.text];
      }
    }
    

    代理方,实现具体的登录流程,委托方不需要知道实现细节。

    // 遵守登录协议
    @interface ViewController () <LoginProtocol> 
    @end
     
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        LoginViewController *loginVC = [[LoginViewController alloc] init];
        loginVC.delegate = self;
        [self.navigationController pushViewController:loginVC animated:YES];
    }
     
    /**
     *  代理方实现具体登录细节
     */
    - (void)userLoginWithUsername:(NSString *)username password:(NSString *)password {
        NSLog(@"username : %@, password : %@", username, password);
    }
    

    这里我们需要知道一下,协议中可以定义哪些内容?协议可以通过@required定义必须实现的代理方法,通过@optional定义可选方法。


    在我们实际开发中,委托方和代理方的关系应该怎么样建立,他们建立的关系的过程中,应该注意哪些问题?

    在使用代理的时候,存在一个循环引用的问题,当代理,协议,委托都通过强引用(strong)形成一个闭环,则会造成内存泄露的问题,此时我们通常会让委托方弱(weak)引用指向代理方来避免循环引用。

    通知(NSNotification)

    • 使用观察者模式来实现的、用于跨层传递消息的机制(一般数据处理逻辑是网络层传递到数据层,然后在经过业务逻辑层加工再去更新UI。如果有时候网络层返回的数据不经过业务逻辑层,直接到达UI层,这时候就用到跨层传递)。
    • 传递方式为一对多

    通知和代理的区别:

    • 通知是观察者模式来实现,代理是由代理模式实现的。
    • 通知传递方式是一对多。代理是传递方式是一对一。

    如何实现通知机制?
    首先,信息的传递就依靠通知(NSNotification),也就是说,通知就是信息(执行的方法,观察者本身(self),参数)的包装。通知中心(NSNotificationCenter)是个单例,向通知中心注册观察者,也就是说,这个通知中心有个集合,这个集合存放着观察者。
    那么这个集合是什么样的数据类型 ? 大概猜想: 发送通知需要name参数,添加观察者也有个name参数,这两个name一样的时候,当发送通知时候,观察者对象就能接受到信息,执行对应的操作。猜想这个集合是NSDictionary
    key就是name,value就是NSArray(存放数据模型),里面存放观察者对象。如下图

    相关文章

      网友评论

        本文标题:iOS的扩展&代理&通知

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