自定义单例传值
前面的几篇文章介绍了通过系统提供的单例进行数据传递,如:UIApplication、通知等,这篇文章介绍使用自定义的单例进行数据传递
我们先在这里约定:界面1传值到界面2为顺传,界面2传值到界面1为逆传
一. 实现步骤
自定义一个单例类,该类要有一个属性用于保存传递的数据
在界面2中,创建单例对象,并把数据赋值给该单例对象的属性
在界面1中,也创建一个单例,然后通过单例对象的属性获取所保存的数据
二. 单例请勿滥用
单例给我们带来方便的同时也有一定的副作用,因为单例对象一旦创建,对象指针是保存在静态区的,单例对象在堆中分配的内存空间只有在程序终止后才会释放,过多的单例必定会增大我们消耗的内存,所以只有当我们确实需要唯一的使用对象时才需要考虑单例模式,切勿滥用单例
三. 具体代码
1. 自定义单例类Tools
----------Tools.h文件
#import <Foundation/Foundation.h>
@interface Tools : NSObject
// 用于保存传递的数据
@property (nonatomic,strong) NSString *str;
+ (instancetype)shareTools;
@end
----------Tools.m文件
#import "Tools.h"
@implementation Tools
+ (instancetype)shareTools
{
Tools *instance = [[self alloc] init];
return instance;
}
//用于存储唯一生成的Tools对象
static Tools *_instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [[super allocWithZone:zone] init];
});
return _instance;
}
- (id)copyWithZone:(NSZone *)zone {
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return _instance;
}
@end
2. AppDelegate类
---------- AppDelegate.m文件
#import "AppDelegate.h"
#include "OneViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. 创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 2. 创建窗口的根控制器
// 2.1 创建导航控制器的根控制器
UIViewController *oneVc = [[OneViewController alloc] init];
// 2.2 创建导航控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:oneVc];
// 2.3 给窗口设置根控制器
self.window.rootViewController = nav;
// 3. 设置窗口为主窗口并显示窗口
[self.window makeKeyAndVisible];
// 隐藏导航控制器的导航条
nav.navigationBarHidden = YES;
return YES;
}
@end
3. OneViewController类
---------- OneViewController.m文件
#import "OneViewController.h"
#import "TwoViewController.h"
#import "Tools.h"
@interface OneViewController ()
@property (nonatomic,strong) UITextField *textField;
@end
@implementation OneViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置控制器View的背景颜色
self.view.backgroundColor = [UIColor greenColor];
// 创建点击按钮
UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clickBtn.frame = CGRectMake(10, 100, 80, 40);
clickBtn.backgroundColor = [UIColor whiteColor];
[clickBtn setTitle:@"到界面2" forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[clickBtn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:clickBtn];
// 创建文本框
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 150, 250, 40)];
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_textField];
}
#pragma mark - 点击事件
- (void)btnClick {
// 创建界面2,并压入栈
TwoViewController *twoVc = [[TwoViewController alloc] init];
[self.navigationController pushViewController:twoVc animated:YES];
}
#pragma mark - 赋值
- (void)viewWillAppear:(BOOL)animated {
// 创建一个单例对象
Tools *data = [Tools shareTools];
// 从单例获取数据
_textField.text = data.str;
}
@end
4. TwoViewController类
---------- TwoViewController.m文件
#import "TwoViewController.h"
#import "Tools.h"
@interface TwoViewController ()
@property (nonatomic,strong) UITextField *textField;
@end
@implementation TwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置控制器View的背景颜色
self.view.backgroundColor = [UIColor yellowColor];
// 创建点击按钮
UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clickBtn.frame = CGRectMake(10, 100, 80, 40);
clickBtn.backgroundColor = [UIColor whiteColor];
[clickBtn setTitle:@"传 值" forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[clickBtn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:clickBtn];
// 创建文本框
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 150, 250, 40)];
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_textField];
}
#pragma mark - 点击事件
- (void)btnClick {
// 创建一个单例对象
Tools *data = [Tools shareTools];
// 保存数据
data.str = _textField.text;
// 跳转界面
[self.navigationController popViewControllerAnimated:YES];
}
@end