页面之间传值方式的总结,五种方式,通知,block,代理,单例,NSUERDEFALUT,

时间:2023-03-09 06:04:54
页面之间传值方式的总结,五种方式,通知,block,代理,单例,NSUERDEFALUT,

首先代码拿上

1:单例

2:通知

3:代理

4:block方法

5:NSUSERDEFAULT(沙盒文件)

先是单例类:

.h文件

@interface DataSource : NSObject
@property (nonatomic, strong) NSString *myName;//单例的属性,用于传值
+(DataSource*)sharedDataSource;//建立单例对象
@end

.m文件

#import "DataSource.h"

@implementation DataSource
+(DataSource *)sharedDataSource{
static DataSource *dataSource = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
dataSource = [DataSource new];
});
return dataSource;
}//返回一个静态的本类对象
@end

接下来是第一个接受传值的页面,使用xib方式创建:

先上.h文件:

#import <UIKit/UIKit.h>
#import "SecondViewController.h"
@interface RootViewController : UIViewController<secondViewDelegate> @end

在上.m文件

#import "RootViewController.h"
#import "SecondViewController.h"
#import "DataSource.h"
@interface RootViewController ()
@property (weak, nonatomic) IBOutlet UILabel *nameLabel; @end @implementation RootViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad];
// 传值方式2:通知:首先注册通知,使用选择器设置接收到通知,调用的方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil];
}
- (IBAction)showSecondView:(id)sender {
SecondViewController *second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
second.delegate = self;//设置代理,传值方法3:代理
second.flag = ;
[self presentViewController:second animated:YES completion:nil];
}
//4.显示的实现
-(void)showName:(NSString *)nameString{
self.nameLabel.text = nameString;
}
//传值方式2:通知:接受到通知,调用该方法显示通知
-(void)ChangeNameNotification:(NSNotification*)notification{
NSDictionary *nameDictionary = [notification userInfo];
self.nameLabel.text = [nameDictionary objectForKey:@"name"];
} //传值方法4:block方法,点击对应按钮出发,设置好传值页面的block方法,进行跳转
- (IBAction)showSecondWithBlock:(id)sender {
SecondViewController *second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; second.flag = ; [self presentViewController:second animated:YES completion:nil]; second.block = ^(NSString *str){
self.nameLabel.text = str;// 传值方法4:设置block方法为更改接收页面label的文本
};
}
//传值方法2:通知,不使用时,删掉通知
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// 通过UserDefault方式取值 if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"myNameText"] length] != ) {
self.nameLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"myNameText"];
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"myNameText"];
}//传值方法5:NSUSERDEFAULT,读取沙盒内的plist文件获取值
//传值方法1: 通过单例取值
DataSource *dataSource = [DataSource sharedDataSource];
if ([dataSource.myName length] != ) {
self.nameLabel.text = dataSource.myName;
dataSource.myName = @"";
}//直接设置或者获取单例对象,单例对象只有一个,所以能够用于传值; }
@end

xib页面包括一个label用于显示,两个跳转按钮,一个正常跳转,另一个需要先设置block,再进行跳转

接下来是第二个传值页面

先是.h文件:

#import <UIKit/UIKit.h>
//block传值1:定义一个block,参数为字符串
typedef void (^ablock)(NSString *str);
//传值方法3:代理 声明协议及方法
@protocol secondViewDelegate
-(void)showName:(NSString *)nameString;
@end
@interface SecondViewController : UIViewController
@property (nonatomic, weak)id<secondViewDelegate> delegate;//传值方法2:代理.设置代理
@property (nonatomic, copy) ablock block;//传值方法4: 定义一个block属性
@property(nonatomic) NSInteger flag;//当前系统标示(0:其他传值方式;1:block传值方式)
@end

再是.m文件:

#import "SecondViewController.h"
#import "DataSource.h"
@interface SecondViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTextField;
@property (weak, nonatomic) IBOutlet UIButton *delegateMethod;
@property (weak, nonatomic) IBOutlet UIButton *notificationMethod;
@property (weak, nonatomic) IBOutlet UIButton *blockMethod;
@property (weak, nonatomic) IBOutlet UIButton *userDefaultMethod;
@property (weak, nonatomic) IBOutlet UIButton *singletonMethod; @end @implementation SecondViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
} - (IBAction)Cancel:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
//传值方式3:调用代理,直接调用代理,跳转接受页面
- (IBAction)delegateMethod:(id)sender {
if ([self notEmpty]) {
[self.delegate showName:self.nameTextField.text];
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self showAlert];
}
} -(IBAction)backDown:(id)sender{
[self.nameTextField resignFirstResponder];
}
//传值方式2:通知.创建一个通知对象及发送通知
- (IBAction)notificationMethod:(id)sender {
if ([self notEmpty]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.nameTextField.text}];
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self showAlert];
}
}
//传值方式4:block传值2:在传值页面中,当输入名字,点击对应的确定按钮后,直接调用本身的block方法,由于跳转之前已经设置为更改接受页面的label,传值成功
- (IBAction)blockMethod:(id)sender {
if ([self notEmpty]) {
if (self.block) {
self.block(self.nameTextField.text);
[self dismissViewControllerAnimated:YES completion:nil];
}
}else{
[self showAlert];
}
}
//用于检测是否输入框为空
-(BOOL)notEmpty{
if ([self.nameTextField.text length] == ) {
return NO;
}
return YES;
} -(void)showAlert{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"请输入名字" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
[alert show];
}
//传值方式5:NSUSERDEFAULT 通过文件或者UserDefault方式存值
- (IBAction)userDefaultMethod:(id)sender {
if ([self notEmpty]) {
[[NSUserDefaults standardUserDefaults] setObject:self.nameTextField.text forKey:@"myNameText"];//使用kvc方法设置
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self showAlert];
}
} //传值方式1:单例 写入要传入的数据(单例对象只有一个,所以能够进行传值)
- (IBAction)singletonMethod:(id)sender {
if ([self notEmpty]) {
DataSource *dataSource = [DataSource sharedDataSource];
dataSource.myName = self.nameTextField.text;
[self dismissViewControllerAnimated:YES completion:nil];
}else{
[self showAlert];
}
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if (self.flag == ) {
self.delegateMethod.hidden = NO;
self.notificationMethod.hidden = NO;
self.blockMethod.hidden = YES;
self.userDefaultMethod.hidden = NO;
self.singletonMethod.hidden = NO;
}else{
self.delegateMethod.hidden = YES;
self.notificationMethod.hidden = YES;
self.blockMethod.hidden = NO;
self.userDefaultMethod.hidden = YES;
self.singletonMethod.hidden = YES;
}
}//根据flag来决定哪些按钮不显示
@end

传值页面的xib依据接受页面的跳转

使用block就只显示block按钮,点击返回

使用正常按钮,就会显示另外其他四种方法.

总结五种传值方法:

1:单例  需要创建单例类,适用于某些特殊场合(例如用户的信息); 使用单例内的方法,可以获得唯一对象(即单例对象),即可以实现传值

//2015-9-23(使用UIApplication 单例,系统级对象传值----随笔《关于UIApplication单例传值》)

2:通知  传值方可以直接创建通知,并发送通知,   而接受方则需要先注册,同时声明接受通知后调用的方法(注意,方法传值是传递NSNotification对象,使用userinfo获取内部的字典)

  

3:代理  代理方需要在委托类内声明一个协议,还需要一个使用该协议的属性, 在委托方则需要先使用协议,并且实现协议内的方法, (由于协议内的方法可以传值给委托方的属性,从而实现传值)!!!!!------注意   在跳转之前,需要在委托方内设置代理方内的代理为本身(委托方)

4:block方法 与代理传值相近, 在传值页面,需要声明一个block属性(该属性内是方法),  在接受方跳转前实现block方法,方法具体实现在接受方,从而达到传值的目的.  跳转完成后,在传值方内调用block属性方法(该属性内是方法),即可实现传值

5:NSUSERDEFAULT(沙盒文件)  存储在沙盒文件内,安全性相对较高,常用于存储用户的偏好设置与用户的登录信息    先使用系统方法获取,再使用kvc的方式设置值,在接受方内使用系统方法获取,使用字典方式获取即可;