oc中反向传值四种方法
block反向传值
在需要传值的界面:
//在传值界面声明一个block属性
//用typedef重新定义block类型
typedef void(^sendBack) (NSString*);
@interface SecondViewController : UIViewController
//用新定义的block类型声明一个属性
@property (nonatomic,copy) sendBack block;
@end
//实现文件中
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
//需要穿的值
_str = @"反向传值";
//传值按钮
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
[button setTitle:@"back" forState:UIControlStateNormal];
[self.view addSubview:button];
[button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchDown];
}
- (void)back{
//调用block属性给并给出要传的参数
_block(_str);
[self dismissViewControllerAnimated:true completion:nil];
}
在接受到传值的界面
//推出下一个界面的方法中
- (void) push{
SecondViewController * secondVC = [[SecondViewController alloc] init];
//调用它的block属性
secondVC.block = ^(NSString * str) {
//把传过来的参数赋给自己的属性
_str = str;
};
[self presentViewController:secondVC animated:true completion:nil];
}
单例反向传值
创建一个单例类
@interface SCffDefault : NSObject
//声明需要传值的属性
@property (nonatomic, assign) NSString *str;
//声明一个外界唯一实例化的方法
+(instancetype)initDefault;
@end
@implementation SCffDefault
//废掉原来默认的初始化方法让它抛出异常
-(instancetype)init {
@throw [NSException exceptionWithName:@"SCffDefaultException" reason:@"不能用init方法创建对象" userInfo:nil];
}
//写一个私有的初始化方法
- (instancetype)initPrivate{
if (self = [super init]) {
}
return self;
}
//实现向外界提供的实例化类方法
+ (instancetype)initDefault {
static SCffDefault * instance = nil;
//使用dispatch_once保证只有一个现场执行此段代码,保证代码唯一性
//此处页可以用@synchronized(self){}来保证单一线程,但没有dispatch_cnce函数好
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!instance) {
instance = [[self alloc] initPrivate];
}
});
return instance;
}
@end
在需要传值的界面
- (void)back{
//创建单例对象给属性赋值
[SCffDefault initDefault].str = _str;
[self dismissViewControllerAnimated:true completion:nil];
}
在接受到到传值的界面
//用单例对象给自己需要赋值的属性赋值
_str = [SCffDefault initDefault].str;
消息中心反向传值
在需要传值的界面
- (void)back{
//创建消息中心单例并发送消息
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendData" object:_str];
[self dismissViewControllerAnimated:true completion:nil];
}
在接受到传值的界面
//注册成为观察者并实现方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(assigementWithNotif:) name:@"sendData" object:nil];
-(void)assigementWithNotif: (NSNotification *)notif{
//给属性赋上传过来的值
NSString * str = notif.object;
_str = str;
}
//最后在dealloc方法中移除观察者
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
使用协议以委托的方式进行传值
在需要传值的界面
//定制传值协议
@protocol sendDataDelegate <NSObject>
-(void) fillwithStr: (NSString *)str;
@end
@interface SecondViewController : UIViewController
//声明代理属性
@property (nonatomic, weak) id<sendDataDelegate> delegate;
@end
//在适当的时机调用协议里面的方法
- (void)back{
//用代理属性调用协议方法
[_delegate fillwithStr:_str];
[self dismissViewControllerAnimated:true completion:nil];
}
在接受到传值的界面
//在push出下个界面的方法中把自己设置成代理对象
- (void) push{
SecondViewController * secondVC = [[SecondViewController alloc] init];
//把下个界面的代理设置为自己
secondVC.delegate = self;
[self presentViewController:secondVC animated:true completion:nil];
}
//遵循协议
@interface FirstViewController ()<sendDataDelegate>
//实现协议中的方法
- (void)fillwithStr:(NSString *)str{
_str = str;
}