1.blok为什么用copy,代理为什么用week
blok
copy可以把bolk放在堆区,防止传递的参数值放在栈区被系统清掉;
代理
week,:类。delegate=self。是强引用;
修饰也用strong 是强引用;
两个强引用造成循环引用;
参考下文
https://www.jianshu.com/p/64125b5617a4
https://www.jianshu.com/p/398472616435
2.原理
代理是方法的变种,逻辑没变,物理位置变化,;blok比代理多了retun多个结果。
3.blok,代理,通知区别 和传递参数
3.1通知
运行机制:
如果注册监听的代码放开发送通知之后执行,侧无法接收到通知。
也就是说:在postNotificationName这句代码执行的时候,在它执行代码之前,所有执行了addObserver的地方会收到通知(《代码逻辑顺序1.1和1.2》),其他地方(《代码逻辑顺序4》)收不到;无论写到哪个控制器里。
一对多:
只要通知发送了,接收的地方(都是在发通知之前执行的)不管有几个地方接收(好比:i = 10 , j=i 所以 i= 10 ,j =10),都会一一执行。
//注册监听第一个控制器,接收通知
//代码逻辑顺序1.1
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(firsr)
name: @"Notification_Send_Message"
object:nil];//这个object 就是传参数用的
//注册监听第二个控制器
//代码执行顺序1.2
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(secend)
name: @"Notification_Send_Message"
object:nil];
//代码执行顺序2 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_Send_Message" object:m_dic];
//代码逻辑顺序4
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(xxxxx)
name: @"Notification_Send_Message"
object:nil];//这个object 就是传参数用的
//上 面的代码发送通一旦执行 下面两个方法都会执行
- (viod)firsr{//代码执行顺序3.1
}
- (viod) secend{//代码执行顺序3.2
}
- (viod) xxxx{//不会被执行
}
//注销监听 跟注册监听写在一个控制器里面
- (void)viewWillDisappear:(BOOL)animated{//逻辑顺序5
[[NSNotificationCenter defaultCenter]removeObserver:selfname:@"Notification_Send_Message"object:nil];
}
3.2block
一对一:
如果两个接收信息代码都运行了(就是下面的《代码执行顺序2》) ,那么下一次信息发送只有一个接收的地方,就是最后一次接收信息的代码那里,前一个接收信息的代码被覆盖了(i = 10 , i= 20,那结果就是i= 20).
但是仍然可以在多个控制器接收,下面是两个控制器都需要回调另一个一个控制器的值,用block 做回调的方法;
运行机制:和通知一样
如果《代码执行顺序3》放在《代码执行顺序2》的前面执行,侧无法接收到回调。
//值传出去
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^ShowTextBlock)(NSString *text);
@interface TextFieldCommViewController : UIViewController
//代码执行顺序1 定义
@property(nonatomic,copy) ShowTextBlock showTextBlock;
@end
NS_ASSUME_NONNULL_END
//值传出的地方
#import "TextFieldCommViewController.h"
@interface TextFieldCommViewController ()
@end
@implementation TextFieldCommViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//点击返回
-(void)complete{
//代码执行顺序3
_showTextBlock(_backTextField.text);
[self.navigationController popViewControllerAnimated:YES];
}
//第一个参数接收的地方:接收传递的参数
@implementation aaaaTableViewController
- (IBAction)eventName:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"xxxx" bundle:nil];
TextFieldCommViewController * refundVC = [sb instantiateViewControllerWithIdentifier:@"TextFieldCommViewController"];
//代码执行顺序2 refundVC.showTextBlock 大括号外的
refundVC.showTextBlock = ^(NSString *text){
//代码执行顺序4 大括号内的
};
[self.navigationController pushViewController:refundVC animated:YES];
}
//第二个参数接收的地方:接收传递的参数
@implementation bbbbbTableViewController
- (IBAction)eventName:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"xxxx" bundle:nil];
TextFieldCommViewController * refundVC = [sb instantiateViewControllerWithIdentifier:@"TextFieldCommViewController"];
//逻辑运行2 refundVC.showTextBlock 大括号外的
refundVC.showTextBlock = ^(NSString *text){
//逻辑运行4 大括号内的
};
[self.navigationController pushViewController:refundVC animated:YES];
}
4代理
运行机制:和通知一样
一对一 和block 一样
代理和block几乎一样
//传递数据的地方
#import <UIKit/UIKit.h>
//代码执行顺序1 定义
@protocol scroViewDelegate <NSObject>
- (void)didleftScroll:(NSString*)strrr;
@end
@interface ORChartView : UIView
//代码执行顺序1 定义
@property (nonatomic, weak) id <scroViewDelegate> delegate;
2.接收值的地方
#import "NewHomeTableViewController.h"
#import "ORChartView.h"
@interface NewHomeTableViewController ()<scroViewDelegate>
@property (nonatomic, strong) ORChartView *chartView;
@end
- (void)viewDidLoad {
[super viewDidLoad];
_chartView = [[ORChartView alloc]init];
_chartView.delegate=self;////代码执行顺序2
}
3.传递数据的地方
//代码执行顺序3
if ([self.delegate respondsToSelector:@selector(didleftScroll:)])
{
[self.delegate didleftScroll :@"sssss"];
}
4.接收数据的地方
#pragma mark 代理
- (void)didleftScroll:(NSString*) strrr{//代码执行顺序4
}
网友评论