三者的区别:通知是一对多,代理和block是一对一。
三者的优缺点:通知:写法简单,但是要注意释放observer,影响内存的消耗,代理:写法复杂,有七步,要设置协议,但是能够灵活的添加所需要的方法,引用也方便。block:写法简单,但是要注意循环引用,调用方法 weakSelf。
BTW简书的页面真是丑到家。
三者的用法
1.通知
//创建通知发出者
NSDictionary* dic =@{@"num":_tf.text,@"price":_tf1.text,@"totalPrice":_dealMoney.text};
[[NSNotificationCenterdefaultCenter]postNotificationName:@"numAndePriceChanged"object:niluserInfo:dic];
//接受通知的对象
-(void)lissionNoti{
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(refreshView:)name:@"numAndePriceChanged"object:nil];
}
-(void)refreshView:(NSNotification*)noti{
NSIndexSet*indexSet=[[NSIndexSetalloc]initWithIndex:[IndexPathintValue]];
NSString* num = noti.userInfo[@"num"];
NSString* price = noti.userInfo[@"price"];
NSString* totalPrice = noti.userInfo[@"totalPrice"];
[ModelsetValue:priceforKey:@"ppPrice"];
[ModelsetValue:totalPriceforKey:@"totalPrice"];
[ModelsetValue:numforKey:@"ppTon"];
[ModelsetValue:totalPriceforKey:@"actualPrice"];
[selfreloadSections:indexSetwithRowAnimation:UITableViewRowAnimationAutomatic];
}
//销毁接收通知的对象,优化内存
-(void)dealloc{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
2.block用法Block是一种比较特殊的数据类型,它可以用于两个界面质检传值,也可以对代码封装作为参数传递。block常常结合typedef来使用(也可以不用,看个人习惯),用自己定义的类型去创建block显得更加的简单便捷,接下来举例实现一个block回调,将传入的参数加上另一个值后再回调回来:
//.h文件-->用来传值的view
#import
// block格式:返回值(^block名字)(参数)
// (1)定义block
typedefvoid(^myBlcok)(NSArray*array);
@interfaceLiuboRegisterViewController :UIViewController
// (2)申明block属性
@property(strong,nonatomic)myBlcokblock;
// (3)初始化方法
- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil withCompletionBlock:(myBlcok)block;
@end
//.m文件 将要传的值保存到代码块里
- (IBAction)registerButtonClick:(id)sender
{
// (5)回调block
if(self.userNameTextField.text.length!=0&&self.passwordTextField.text.length!=0&&self.confirmPasswordTextField.text.length!=0&&self.emailTextField.text.length!=0)
{
//装入数组里面
NSArray*array = [NSArrayarrayWithObjects:self.userNameTextField.text,self.passwordTextField.text,nil];
if(self.block)
{
self.block(array);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
}
//需要得到block里值的.m文件
#pragma mark -注册
- (IBAction)registerButtonClick:(id)sender
{
//LiuboRegisterViewController *registerViewController = [[LiuboRegisterViewController alloc] initWithNibName:@"LiuboRegisterViewController" bundle:nil];
// block回调方法
LiuboRegisterViewController*registerViewController = [[LiuboRegisterViewControlleralloc]initWithNibName:@"LiuboRegisterViewController"bundle:nilwithCompletionBlock:^(NSArray*array)
{
if([arraycount] !=0)
{
self.userNameTextField.text= array[0];
self.passwordTextField.text= array[1];
}
}];
UINavigationController*navigationController = [[UINavigationControlleralloc]initWithRootViewController:registerViewController];
[selfpresentViewController:navigationControlleranimated:YEScompletion:^{
}];
}
3.代理
委托其实是一种设计模式,通俗一点来讲就是当自己有需求要处理但是不方便的时候,就建立一个委托,请别人来帮忙处理。举个例子:“我要给路人甲打电话,但是我不知道李斯的电话号码;我就拜托章三去查询,章三查到后就发短信给了我号码”,章三就是我的委托对象。相信大家在ios开发中经常会看到类似@protocol(协议)的代码吧!如果我们要实现一个delegate委托,就先要先定义protocol(协议),在指定收到回调的类中(也就是我)去实现协议中的函数(例如收短信),如果没有实现,编译器就会报警告;下面是一个简单的例子,SecondviewController会回调FirstViewController,FirstViewController实现协议中的回调函数
//.h文件
#import
// (1)创建协议
@protocolLiuboRegisterViewControllerDelegate
//必须要实现的协议方法
//@required
//可选择性实现的协议方法
// (2)申明协议方法
@optional
- (void)sendVaules:(NSArray*)array;
@end
@interfaceLiuboRegisterViewController :UIViewController
// (3)申明代理
@property(assign,nonatomic)iddelegate;
@end
//.m文件
- (IBAction)registerButtonClick:(id)sender
{
if(self.userNameTextField.text.length!=0&&self.passwordTextField.text.length!=0&&self.confirmPasswordTextField.text.length!=0&&self.emailTextField.text.length!=0)
{
//保存到数组里面
NSArray*array = [NSArrayarrayWithObjects:self.userNameTextField.text,self.passwordTextField.text,nil];
// (4)回调协议方法
if([self.delegaterespondsToSelector:@selector(sendVaules:)])
{
[self.delegatesendVaules:array];
}
[selfdismissViewControllerAnimated:YEScompletion:^{
}];
}
}
//.h文件
// (5)添加代理
@interfaceLiuboLoginViewController()<LiuboRegisterViewControllerDelegate>
#pragma mark -注册
- (IBAction)registerButtonClick:(id)sender
{
LiuboRegisterViewController*registerViewController = [[LiuboRegisterViewControlleralloc]initWithNibName:@"LiuboRegisterViewController"bundle:nil];
// (6)设置代理
registerViewController.delegate=self;
UINavigationController*navigationController = [[UINavigationControlleralloc]initWithRootViewController:registerViewController];
[self presentViewController:navigationController animated:YES completion:nil
}
// (7)响应回调的协议方法
- (void)sendVaules:(NSArray*)array
{
if([arraycount] !=0)
{
NSString*userName = array[0];
NSString*password = array[1];
self.userNameTextField.text= userName;
self.passwordTextField.text= password;
}
}
网友评论