文章目录
单例传值
什么是单例
单例 = 全局唯一的对象,任何地方都能访问它
举例讲解
VCSecond 有一个 TextField,输入文字后通过通知传给 VCFirst 的 Label 显示
创建单例类, 设置要共享的数据
objc
// DataManager.h
@interface DataManager : UIViewController
// 获取单例的方法
- (instancetype) shareManager;
// 要共享的数据
@property (nonatomic, copy) NSString* shareText;
@end
实现单例, 保证每次创建出的DataManager对象都唯一
objc
// DataManager.m
// 实现单例
+ (instancetype)shareManager {
static DataManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[super allocWithZone: NULL] init];
});
return instance;
}
+ (instancetype) allocWithZone: (struct _NSZone*) zone {
return [self shareManager];
}
- (id) copyWithZone: (NSZone*) zone {
return self;
}
- (id) mutableCopy: (NSZone*) zone {
return self;
}
定义VCFirst 的showLabel属性 , 显示接收到的值
objc
#import <UIKit/UIKit.h>
#import "VCSecond.h"
#import "DataManager.h" // 引入单例
@interface VCFirst : UIViewController
@property (nonatomic) UILabel* showLabel;
@end
创建label, button,显示传值的内容, 并通过事件调用切换视图控制器
objc
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"VCFirst";
// 创建显示 Label
self.showLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 250, 300, 50)];
self.showLabel.textAlignment = NSTextAlignmentCenter;
self.showLabel.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview: self.showLabel];
// 创建跳转按钮
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithTitle: @"next" style: UIBarButtonItemStylePlain target: self action: @selector(pushToSecond)];
self.navigationItem.rightBarButtonItem = item;
}
每次都从单例中读取数据,因为实现了单例, 所以每次创建的 DataManager 对象都唯一, 因此DataManager 对象可以作为媒介在不同的视图控制器间传递数据
objc
// VCFirst.m
// 从单例中读取数据
NSString* saveText = [DataManager shareManager].shareText;
if (saveText.length > 0) {
self.showLabel.text = [NSString stringWithFormat: @"上次保存: %@", saveText];
} else {
self.showLabel.text = @"等待接收文字...";
}
设置按钮事件, 创建VCSecond视图并跳转
objc
// VCFirst.m
- (void) pushToSecond {
VCSecond* vc = [[VCSecond alloc] init];
[self.navigationController pushViewController: vc animated: YES];
}
通过viewWillAppear: (BOOL)animate方法在每次加载到VCFirst的时候都更新数据
objc
// VCFirst.m
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
// 每次回到这个界面时, 重新读取单例中的最新数据
NSString* latesText = [DataManager shareManager].shareText;
if (latesText.length > 0) {
self.showLabel.text = [NSString stringWithFormat: @"上次保存: %@", latesText];
}
}
在VCSsecond中定义并创建 UITextField 类型属性 inputTextField, 用于输入需要传值的内容
objc
// VCSecond.m
@interface VCSecond ()
@property (nonatomic, strong) UITextField *inputTextField;
@property (nonatomic, strong) UIButton *sendButton;
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"VCSecond";
// 创建输入框
self.inputTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 250, 275, 44)];
self.inputTextField.borderStyle = UITextBorderStyleRoundedRect;
self.inputTextField.placeholder = @"请输入文字";
[self.view addSubview:self.inputTextField];
// 创建发送按钮
UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithTitle: @"back" style: UIBarButtonItemStylePlain target: self action: @selector(pressSave)];
self.navigationItem.rightBarButtonItem = item;
}
设置按钮事件, 返回 VCFirst 并将 VCSecond 中inputTextField 的text值保存到单例中, 用于VCFirst 中通过单例接受传递的值
objc
// VCSecond.m
- (void) pressSave {
NSString* inputText = self.inputTextField.text;
if (inputText.length == 0) {
inputText = @"空消息";
}
// 把数据存入单例
[DataManager shareManager].shareText = inputText;
NSLog(@"已保存到单例: %@", inputText);
// 返回
[self.navigationController popViewControllerAnimated: YES];
}
效果如下
