2023年7月14日发(作者:)
OC监听-Block代理通知KVO(源码)⼀直觉得⾃⼰写的不是技术,⽽是情怀,⼀个个的教程是⾃⼰这⼀路⾛来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少⾛弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。Blockblock记得 刚开始学ios的时候,看了很多次都不会⽤,也感觉很难理解,直到后来看了⼈家的代码结合需求,终于搞明⽩了。block可以作为属性使⽤声明block作为属性的命名有两种写法的:宏定义block 宏定义//先宏定义typedef void(^CallBlockOneParameter)(NSString *value1);//再声明@property (nonatomic,copy)CallBlockEmpty callBlockEmpty;直接声明@property (nonatomic,copy)void(^CallBlockEmpty)(NSString *name);使⽤在⼀个类的.h声明⼀个block属性。.m点击按键把值传递到block⾥⾯。在外⾯可以通过类来点出属性拿到从⾥⾯传出来的值实现的效果:block可以作为⽅法的参数使⽤#import NS_ASSUME_NONNULL_BEGINtypedef void(^ReportViewBlock) (NSString* value);@interface ReportView : UIView+(void)showWithReportWithView:(UIView *)view WithBlock:(ReportViewBlock)block;@endNS_ASSUME_NONNULL_END.m⽂件的代码#import "ReportView.h"#import "NerdyUI.h"@interface ReportView()@property (nonatomic,copy) ReportViewBlock block;@property (nonatomic,strong) UIButton *btn;@end@implementation ReportView+(void)showWithReportWithView:(UIView *)view WithBlock:(ReportViewBlock)block{ ReportView *tipView = [[ReportView alloc] initWithFrame:CGRectZero withCallBlock:block]; (view).makeCons(^{ (view); });}- (instancetype)initWithFrame:(CGRect)frame withCallBlock:(ReportViewBlock)callBlock{ self = [super initWithFrame:frame]; = callBlock; [self buildUI]; return self;}- (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; [self buildUI]; return self;}-(void) buildUI{ oundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; = [UIButton new]; [ addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; (self).bgColor([UIColor orangeColor]).str(@"btn").color([UIColor whiteColor]).fnt(16).borderRadius(4).makeCons(^{ (self); nts(50); });}-(void)btnClick:(UIButton *)btn{ (@"按键");}@end然后再外⾯的控制器⾥⾯使⽤[ReportView showWithReportWithView: WithBlock:^(NSString * _Nonnull value) { NSLog(@"value: %@",value);}];实现的效果:代理代理其实就是协议⼀样的:在数据传值的下⾯是代理的参考代码:有值的控制器:1.创建代理协议2.创建代理属性3.触发代理⽅法想得到值的控制器1.遵守代理2.制定代理对象3.实现代理⽅法@class DinnerView;// 创建代理协议跟代理⽅法@protocol DinnerViewDelegate - (void)dinnerView:(DinnerView *)view btnClick:(UIButton *)btn;@end// 创建代理属性@property (nonatomic, weak)id delegate;//盘算代理是否实现if ([te respondsToSelector:@selector(dinnerView:btnClick:)]) { [te dinnerView:self btnClick:btn];}制定控制器实现的代理[DinnerView new].delegate = self.#pragma mark DinnerViewDelegate- (void) dinnerView:(DinnerView *)view btnClick:(UIButton *)btn {
}创建协议⽅法的时候默认是要实现的,可以设置协议⽅法可选择实现的。需要加⼀个标志:@required 之下的⽅法是必须实现的,不然编译器会发出警报@optional 之下的⽅法是可选实现的。通知通知也能够⽤于数据的逆传的,刚刚上⾯的代理使⽤数据的逆传⼀般是B控制器返回值给A控制器 A B之前是有关系的,或者A的控制的view或者cell把值返回到控制器⼀般⽤代理,那么通知⼀般的使⽤⼀般都是有值的控制器或者view跟想拿到值的控制器或者view两个之间是毫⽆关联的关系就⽤到通知来去实现的。不过通知可以⽀持⼀发多收的话我没有试过,这个上⽹查⼀下应该有的。举个例⼦:我使⽤过通知的需求,当时公司的极光推送功能收到消息之后,弹出的view是在⾸页的底部弹出来的,这个需要⾃⼰⾃定义的,那么我会在AppDelegate⾥⾯收到信息就发送通知给⾸页,然后⾸页收到通知之后就弹出⼀个view来。下⾯是通知的参考代码//有值 的控制器NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"<#值#>",@"text", nil];//创建通知NSNotification *notification =[NSNotification notificationWithName:@"tongzhi" object:nil userInfo:dict];//通过通知中⼼发送通知[[NSNotificationCenter defaultCenter] postNotification:notification];//想得到值 的控制器//注册通知[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tongzhiActionClick:)name:@"tongzhi" object:nil];- (void)tongzhiActionClick:(NSNotification *)text{ = fo[@"text"]; NSLog(@"%@",fo[@"text"]); NSLog(@"-----接收到通知------");}//移除通知-(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self];}KVO下⾯是使⽤KVO的参考代码://注册监听[self.<#类型#> addObserver:self forKeyPath:@"<#属性名称#>" options:NSKeyValueObservingOptionNew context:nil];//实现监听⽅法- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { id oldName = [change objectForKey:NSKeyValueChangeOldKey]; NSLog(@"oldName----------%@",oldName); id newName = [change objectForKey:NSKeyValueChangeNewKey]; NSLog(@"newName-----------%@",newName); //当界⾯要消失的时候,移除kvo // [object removeObserver:self forKeyPath:@"name"];}//取消监听⽅法- (void)dealloc { [self.<#类名#> removeObserver:self forKeyPath:@"<#属性名称#>"]; self.<#类名#>n = nil;}假如我想监听person类⾥⾯的属性name,如果想⽤KVO去监听这个属性的变化的时候就触发监听的⽅法必须要实现setter的⽅法:在person的类⾥⾯有两个⽅法是这样的。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689264457a226421.html
评论列表(0条)