iOS的扩展&代理&通知


扩展(Extension)

一般用扩展来做什么?

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

扩展的特点:

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

分类和扩展的区别:

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

代理(Delegate):

什么是代理:

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


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

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

#import 
@protocol LoginProtocol 
@optional
- (void)userLoginWithUsername:(NSString *)username password:(NSString *)password;
@end

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

#import 
#import "LoginProtocol.h"
/**
 *  当前类是委托类。用户登录后,让代理对象去实现登录的具体细节,委托类不需要知道其中实现的具体细节。
 */
@interface LoginViewController : UIViewController
// 通过属性来设置代理对象
@property (nonatomic, weak) id 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 ()  
@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的扩展&代理&通知)