技术iOSios

ios 常见的几种逆向传值方式

2015-11-06  本文已影响7173人  静心_安神

在iOS开发中,常见的几种逆向传值方式,有代理(delegate)、通知(NSNotification),block等等,其实还有一种方法。

   1、委托代理

delegate只能是一对一之间的。他只能是navigation的栈里面的相邻控制器传值, 不能跨控制器传值。比如:a到b,b到c.,而不能从c传到a.

@protocol PassValueDelegate<NSobject>

@optional

- (void)VCValuePass:(UIViewController*)VC;

@end

delegate 为什么用assign, 这还是一道面试题呢

@property(assign,nonatomic)id delegate;

if([self.delegaterespondsToSelector:@selector(VCValuePass:)]){

[self.delegateVCValuePass:self];

[self.navigationControllerpopViewControllerAnimated:YES];}


2、通知(NSNotifacation)

通知的用处就随意多了, 首先他是多对多传值的, 不过要先注册成为监听者,才能收到通知。简单、便捷。不用通知的时候,记得移除。

2.1.发出通知 // object通知发布者(是谁要发布通知)userInfo:一些额外的信息(通知发布者传递给通知接收者的信息内容)

NSDictionary* dic =@{ @"name":@"翠花", @"sex":@"女"};

NSString* address =@"深圳特区";[[NSNotificationCenterdefaultCenter]postNotificationName:@"ValuePass"object:addressuserInfo:dic];

2.2.注册监听对象  name通知的名称。如果为nil,那么无论通知的名称是什么,监听器都能收到这个通知;  Object通知发布者。如果为anObject和aName都为nil,监听器都收到所有的通知

[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(receiveValue:)name:@"ValuePass"object:nil];

- (void)receiveValue:(NSNotification* )notifi{

NSLog(@"%@, %@",notifi.object, notifi.userInfo);}

在注册成为监听者的页面, 要注意移除通知

- (void)receiveValue:(NSNotification* )notifi{

NSLog(@"%@, %@",notifi.object, notifi.userInfo);}

写到这里的时候,我还是block使用的小白, 只会一些简单的block使用,那天自己block精通了,在详细讲一下。

3、block

我使用的block主要是作为property属性实现页面之间传值。

__block关键字的主要作用是:__block对象在block中是可以被修改、重新赋值的。__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

__block和__weak关键字的区别:

__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。__block对象可以在block中被重新赋值,__weak不可以。__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。

情景描绘:由a控制器调到b,首先在b的.h文件声明

@property(copy,nonatomic)void(^passValueBlock)(NSDictionary* dict);// 刚刚把copy写成assign,一直再报错

在b的.m里面,想传值的时候在方法里面写上

NSDictionary* dic =@{@"name":@"翠花",@"sex":@"女"};

if(self.passValueBlock)

self.passValueBlock(dic);

在a的.m文件里写:

__blockViewController* blockSelf =self;

TwoViewController* twoVC = [[TwoViewControlleralloc]init];

twoVC.passValueBlock= ^(NSDictionary* dict){

[blockSelfgetdic:dict];};

4、传值

最后一种传值方式,是在无意中发现的,但也能传值。之前一直做a到b,b到c,c到d等等之类的控制器跳转的项目, 然后从后面的某个控制器跳转到前面的某个控制器。解决办法就是找到需要跳转的控制器,在导航控制器栈中的位置,然后跳转,后来发现,如果在需要跳转的控制器的.h文件声明一个变量,在跳转之前赋值,是可以传过去的。

在d控制器的方法:

ViewController* a =self.navigationController.viewControllers[0];

a.name=@"翠花";

[self.navigationControllerpopToViewController:oneVCanimated:YES];

但是有时候,a控制器在栈里面的位置不一样,所以index不一定是固定某个值,另一种方法

ViewController* oneVC =nil;

for(UIViewController* VCinself.navigationController.viewControllers){

if([VCisKindOfClass:[ViewControllerclass]]){

oneVC =(ViewController*) VC;

oneVC.name=@"翠花";

[self.navigationControllerpopToViewController:oneVCanimated:YES];}

}

在a控制器验证一下:

- (void)setName:(NSString*)name{

_name= name;

NSLog(@"%@",name);}

上一篇下一篇

猜你喜欢

热点阅读