傳值需求
- 將用戶信息 userInfo 作為傳值對(duì)象進(jìn)行傳遞。
場(chǎng)景一 主頁傳值到詳情頁
- 現(xiàn)在模擬傳遞用戶名:userName。
屬性傳值
- 屬性傳值一般用于從主頁傳值到詳情頁。
- 傳值步驟:
steps 1:在DetailViewController.h文件中將需要獲取的值聲明成屬性。
#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController
@property (nonatomic, strong)NSString *userInfo; /**< 用戶信息 */
@end
steps 2:在HomeViewController.m文件中導(dǎo)入頭文件“DetailViewController.h”,然后在界面跳轉(zhuǎn)邏輯處理方法中初始化DetailViewController粟誓,并通過點(diǎn)語法給屬性u(píng)serInfo賦需要傳遞的值。
- (void)respondsToButton:(UIButton *)sender {
// 初始化詳情視圖控制器n
DetailViewController *detailVc = [[DetailViewController alloc] init];
// 屬性傳值:賦值
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
detailVc.userInfo = userInfo;
// 模態(tài)切換(界面跳轉(zhuǎn))
[self presentViewController:detailVc animated:YES completion:nil];
}
steps 3:在DetailViewController.m文件viewDidLoad方法中獲取userName的值起意,此時(shí)獲取到的值就是從主頁傳過來的值鹰服。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@", userInfo);
}
init傳值
- init方法傳值與屬性傳值類似,一般用于從主頁傳值到詳情頁。
steps 1:在DetailViewController.h文件中聲明init方法悲酷。
- (instancetype)initWithUserInfo:(NSDictionary *)userInfo; /**< init傳值方法聲明 */
steps 2:在HomeViewController.m文件中導(dǎo)入頭文件“DetailViewController.h”套菜,然后在界面跳轉(zhuǎn)邏輯處理方法中通過initWithUserInfo:方法初始化DetailViewController并賦值。
- (void)respondsToButton:(UIButton *)sender {
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
// 初始化詳情視圖控制器
DetailViewController *detailVc = [[DetailViewController alloc] initWithUserInfo:userInfo];
// 模態(tài)切換(界面跳轉(zhuǎn))
[self presentViewController:detailVc animated:YES completion:nil];
}
steps 3:在DetailViewController.m文件中重寫init方法设易,即實(shí)現(xiàn)initWithUserInfo:方法笼踩,在這個(gè)方法中獲取userName的值,此時(shí)獲取到的值就是從主頁傳過來的值亡嫌。
- (instancetype)initWithUserInfo:(NSDictionary *)userInfo {
if (self = [super init]) {
NSLog(@"%@", userInfo);
}
return self;
}
場(chǎng)景二 詳情頁傳值到主頁
Block塊傳值
- block在傳值中主要用于回調(diào),現(xiàn)模擬從詳情視圖控制器傳值到主頁視圖控制器掘而。
steps 1:在 DetailViewController.h文件中聲明block類型挟冠、屬性以及block回調(diào)方法。
#import <UIKit/UIKit.h>
// 1 聲明block類型
typedef void(^CallBackBlock)(NSString *context);
@interface DetailViewController : UIViewController
// 2 聲明block屬性
@property (nonatomic, copy) CallBackBlock callBackBlock;
/ 3 聲明block傳值方法
- (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock;
@end
steps 2:在 DetailViewController.m文件中袍睡,實(shí)現(xiàn)如下操作:
// 4 賦值屬性block
- (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock {
self.callBackBlock = callBackBlock;
}
// 處理按鈕點(diǎn)擊
- (void)respondsToButtonClick:(UIButton *)sender {
// 5 傳值
if (self.callBack) {
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
self.callBackBlock(userInfo);
[self dismissViewControllerAnimated:YES completion:nil];
}
}
steps 3:在 ViewController.m文件實(shí)現(xiàn)如下操作:
- (void)respondsToButtonClick:(UIButton *)sender {
DetailViewController *detailVc = [[DetailViewController alloc] init];
// 6 調(diào)用block知染,取值
[detailVc getsUserInfoWithBlocks:^(NSDictionary *userInfo) {
NSLog(@"%@", userInfo);
}];
// 模態(tài)切換(界面跳轉(zhuǎn))
[self presentViewController:detailVc animated:YES completion:nil];
}
- Tips:
1、為block取別名斑胜,可在參數(shù)列表中將需要傳遞的參數(shù)寫成形參控淡;
2、設(shè)置block屬性注意使用copy關(guān)鍵字止潘;
3掺炭、設(shè)置一個(gè)方法持有當(dāng)前block;
4凭戴、在合適的地方進(jìn)行調(diào)用類似于代理涧狮;
5、在創(chuàng)建該對(duì)象的地方進(jìn)行block方面的調(diào)用么夫;
協(xié)議傳值
- 協(xié)議傳值又稱代理傳值者冤,可直接將需要傳遞的值從委托方傳送至代理人,協(xié)議傳值可用于從下一個(gè)視圖控制器傳值到上一個(gè)視圖控制器(詳情頁傳值到主頁)档痪,現(xiàn)假定主頁是詳情頁的代理涉枫。
- 傳值步驟
steps 1:在DetailViewController.h文件中聲明協(xié)議,并且設(shè)置代理屬性腐螟。
#import <UIKit/UIKit.h>
// @class 意在告訴編譯器愿汰,“DetailViewController”為一個(gè)類。
@class DetailViewController;
// @protocol 聲明協(xié)議
// 協(xié)議命名規(guī)范:類名 + delegate
@protocol DetailViewControllerDelegate <NSObject>
// @optional:聲明可選協(xié)議方法
// 協(xié)議方法的聲明模仿蘋果官方聲明方式遭垛,將類實(shí)例以及傳遞信息一并暴露在參數(shù)中
@optional
- (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo;
@end
@interface DetailViewController : UIViewController
// 聲明代理屬性尼桶,注意關(guān)鍵字使用 weak || assign,可避免保留環(huán)
@property (nonatomic, weak) id <DetailViewControllerDelegate> delegate;
@end
steps 2:在DetailViewController.m文件處理返回按鈕方法中調(diào)用協(xié)議方法傳值锯仪。
- (void)respondsToButton:(UIButton *)sender {
// 首先判斷代理人是否存在并且是否遵守協(xié)議并且實(shí)現(xiàn)了協(xié)議方法
if (_delegate && [_delegate respondsToSelector:@selector(detailViewController:goBackWithUserInfo:)]) {
// 如果滿足判斷條件泵督,則讓代理執(zhí)行協(xié)議方法,此處讓代理人執(zhí)行協(xié)議方法庶喜,在代理人那個(gè)控制器中的協(xié)議方法會(huì)被執(zhí)行小腊;
// 通常經(jīng)協(xié)議傳值在此處調(diào)用方法時(shí)救鲤,直接給參數(shù)賦值即可,在代理人控制器實(shí)現(xiàn)的協(xié)議方法中秩冈,可直接獲取此處設(shè)置的值本缠;
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
[_delegate detailViewController:self goBackWithUserInfo:userInfo];
}
}
steps 3:在HomeViewController.m文件處理界面跳轉(zhuǎn)按鈕方法中初始化詳情視圖控制器,設(shè)置詳情視圖控制器協(xié)議代理為self(主頁)入问,并且遵守<DetailViewControllerDelegate>協(xié)議丹锹。
- (void)respondsToButton:(UIButton *)sender {
// 初始化詳情視圖控制器
DetailViewController *detailVc = [[DetailViewController alloc] init];
// 設(shè)置代理,并且遵守<DetailViewControllerDelegate>
detailVc.delegate = self;
// 模態(tài)切換(界面跳轉(zhuǎn))
[self presentViewController:detailVc animated:YES completion:nil];
}
steps 4:在HomeViewController.m中實(shí)現(xiàn)<DetailViewControllerDelegate>協(xié)議方法芬失,獲取值楣黍。
#pragma mark *** DetailViewControllerDelegate ***
// 實(shí)現(xiàn)協(xié)議方法,獲取值
- (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo {
NSLog(@"%@", userInfo);
}
場(chǎng)景三 多界面?zhèn)髦?/h3>
通知傳值
- 通知傳值適用于任意控制器(界面)棱烂,不管兩個(gè)控制器之間是否有關(guān)聯(lián)租漂,只需滿足一個(gè)條件,在傳值的時(shí)候必須保證通知已經(jīng)被設(shè)定颊糜,即已添加通知(觀察者observer)×ㄖ危現(xiàn)假設(shè)從詳情界面?zhèn)髦档街鹘缑妫磸南乱粋€(gè)界面?zhèn)髦档缴弦粋€(gè)界面衬鱼,具體實(shí)現(xiàn)方式如下业筏。
- 傳值步驟
steps 1:注冊(cè)通知:為保證在傳值時(shí)通知已經(jīng)被設(shè)定,因此需要在HomeViewController.m文件中注冊(cè)通知鸟赫。
#import "HomeViewController.h"
#import "DetailViewController.h"
@interface HomeViewController ()
@end
@implementation HomeViewController
- (instancetype)init {
self = [super init];
if (self) {
/**
* 注冊(cè)通知
*
* @param observer 觀察者對(duì)象
* @param selector 觸發(fā)方法驾孔,即當(dāng)收到通知之后執(zhí)行的方法
* @param name 通知代號(hào),即通知標(biāo)識(shí)惯疙,發(fā)送通知時(shí)的標(biāo)識(shí)必須和注冊(cè)通知時(shí)的標(biāo)識(shí)一致
* @param object 是否傳值翠勉,在注冊(cè)通知的時(shí)候無需值,因此此處可填nil
*
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondsToNotification:) name:@"notification_name" object:nil];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark *** responds notification ***
// 處理通知霉颠,當(dāng)接收到通知的時(shí)候該方法會(huì)自動(dòng)調(diào)用
// 在此處獲取從發(fā)送通知的控制器傳過來的值
- (void)respondsToNotification:(NSNotification *)info {
}
steps 2:發(fā)送通知:在DetailViewController.m文件處理返回按鈕方法中对碌,發(fā)送通知,傳值到主界面蒿偎,發(fā)送通知時(shí)的標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致朽们。
- (void)respondsToButton:(UIButton *)sender {
// 發(fā)送通知:通知標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致
// 將需要傳遞的信息以字典形式賦給 userInfo 參數(shù)
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification_name" object:nil userInfo:userInfo];
}
steps 3:處理通知:在HomeViewController.m文件處理通知方法中,獲取值诉位。
#pragma mark *** responds notification ***
// 處理通知骑脱,在此處獲取從發(fā)送通知的控制器傳過來的值
// 注意:info參數(shù)包含兩個(gè)屬性,可通過點(diǎn)語法訪問苍糠。
// 1叁丧、name:為對(duì)應(yīng)通知的標(biāo)識(shí)
// 2、userInfo:為傳遞的信息
- (void)respondsToNotification:(NSNotification *)info {
NSLog(@"%@", info.userInfo);
}
steps 4:移除通知:通知在界面被釋放的時(shí)候一定記得移除,否則可能會(huì)導(dǎo)致程序的奔潰拥娄。移除通知在注冊(cè)通知控制器中的[dealloc]方法中實(shí)現(xiàn)蚊锹。
- (void)dealloc
{
// 移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- 注意
1、通知傳值的使用會(huì)貫穿如下4個(gè)步驟:注冊(cè)通知 -> 發(fā)送通知 -> 處理通知 -> 移除通知
2稚瘾、通知必須先注冊(cè)再使用牡昆,通知必須在不需要的時(shí)候調(diào)用remove方法移除。
單例傳值
- 單例貫穿整個(gè)應(yīng)用程序聲明周期摊欠,利用單例傳值適用于任何控制器丢烘,使用前提是在獲取值的時(shí)候必須保證單例屬性有值,否則獲取值為nil些椒,此處模擬從主頁視圖控制器傳值到詳情視圖控制器铅协。
- 傳值步驟
steps 1:創(chuàng)建單例,繼承于NSObject摊沉,任意命名,必須符合規(guī)范痒给。此處創(chuàng)建單例類名為Singleton说墨。
steps 2:在Singleton.h中聲明傳值屬性,并且聲明單例類便利構(gòu)造器苍柏。
@interface Singleton : NSObject
@property (nonatomic, strong) NSDictionary *userInfo; /**< 單例屬性 */
+ (instancetype)defaultSingleton; /**< 單例便利構(gòu)造器 */
@end
steps 3:在Singleton.m文件中實(shí)現(xiàn)遍歷構(gòu)造器方法尼斧。
#import "Singleton.h"
static Singleton *singleton = nil;
@implementation Singleton
+ (instancetype)defaultSingleton {
// GCD創(chuàng)建單例,效率更高试吁,性能更好棺棵,消耗更低。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[Singleton alloc] init];
});
return singleton;
}
@end
steps 4:在HomeViewController.m文件中獲取單例實(shí)例熄捍,并且賦值單例屬性烛恤,賦值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 單例屬性賦值
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取單例實(shí)例余耽,首先需導(dǎo)入Singleton.h
Singleton *singleton = [Singleton defaultSingleton];
// 單例屬性賦值
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
singleton.userInfo = userInfo;
}
steps 5:在DetailViewController.m文件中獲取單例屬性缚柏,取值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 獲取單例屬性
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取單例實(shí)例碟贾,首先需導(dǎo)入Singleton.h
Singleton *singleton = [Singleton defaultSingleton];
// 獲取單例屬性值
NSLog(@"%@", singleton.userInfo);
}
NSUserDefaults傳值
- NSUserDefaults系統(tǒng)單例傳值和自定義單例傳值基本一致币喧,首先需保證NSUserDefaults對(duì)應(yīng)key中有值,此處模擬主頁視圖控制器傳值到詳情視圖控制器
- 傳值步驟
steps 1:在HomeViewController.m中獲取NSUserDefaults實(shí)例袱耽,并且存值杀餐。
- (void)saveValueInUserDefaults {
// 獲取NSUserDefaults實(shí)例
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 存值
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
[defaults setObject:userInfo forKey:@"userInfo"];
// 同步數(shù)據(jù)
[defaults synchronize];
}
steps 2:在DetailViewController.m中獲取值
- (void)getValueInUserDefaults {
// 獲取NSUserDefaults實(shí)例
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 根據(jù)key獲取值
NSDictionary *userInfo = [defaults objectForKey:@"userInfo"];
NSLog(@"%@", userInfo);
}
steps 1:注冊(cè)通知:為保證在傳值時(shí)通知已經(jīng)被設(shè)定,因此需要在HomeViewController.m文件中注冊(cè)通知鸟赫。
#import "HomeViewController.h"
#import "DetailViewController.h"
@interface HomeViewController ()
@end
@implementation HomeViewController
- (instancetype)init {
self = [super init];
if (self) {
/**
* 注冊(cè)通知
*
* @param observer 觀察者對(duì)象
* @param selector 觸發(fā)方法驾孔,即當(dāng)收到通知之后執(zhí)行的方法
* @param name 通知代號(hào),即通知標(biāo)識(shí)惯疙,發(fā)送通知時(shí)的標(biāo)識(shí)必須和注冊(cè)通知時(shí)的標(biāo)識(shí)一致
* @param object 是否傳值翠勉,在注冊(cè)通知的時(shí)候無需值,因此此處可填nil
*
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondsToNotification:) name:@"notification_name" object:nil];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark *** responds notification ***
// 處理通知霉颠,當(dāng)接收到通知的時(shí)候該方法會(huì)自動(dòng)調(diào)用
// 在此處獲取從發(fā)送通知的控制器傳過來的值
- (void)respondsToNotification:(NSNotification *)info {
}
steps 2:發(fā)送通知:在DetailViewController.m文件處理返回按鈕方法中对碌,發(fā)送通知,傳值到主界面蒿偎,發(fā)送通知時(shí)的標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致朽们。
- (void)respondsToButton:(UIButton *)sender {
// 發(fā)送通知:通知標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致
// 將需要傳遞的信息以字典形式賦給 userInfo 參數(shù)
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification_name" object:nil userInfo:userInfo];
}
steps 3:處理通知:在HomeViewController.m文件處理通知方法中,獲取值诉位。
#pragma mark *** responds notification ***
// 處理通知骑脱,在此處獲取從發(fā)送通知的控制器傳過來的值
// 注意:info參數(shù)包含兩個(gè)屬性,可通過點(diǎn)語法訪問苍糠。
// 1叁丧、name:為對(duì)應(yīng)通知的標(biāo)識(shí)
// 2、userInfo:為傳遞的信息
- (void)respondsToNotification:(NSNotification *)info {
NSLog(@"%@", info.userInfo);
}
steps 4:移除通知:通知在界面被釋放的時(shí)候一定記得移除,否則可能會(huì)導(dǎo)致程序的奔潰拥娄。移除通知在注冊(cè)通知控制器中的[dealloc]方法中實(shí)現(xiàn)蚊锹。
- (void)dealloc
{
// 移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
1、通知傳值的使用會(huì)貫穿如下4個(gè)步驟:注冊(cè)通知 -> 發(fā)送通知 -> 處理通知 -> 移除通知
2稚瘾、通知必須先注冊(cè)再使用牡昆,通知必須在不需要的時(shí)候調(diào)用remove方法移除。
steps 1:創(chuàng)建單例,繼承于NSObject摊沉,任意命名,必須符合規(guī)范痒给。此處創(chuàng)建單例類名為Singleton说墨。
steps 2:在Singleton.h中聲明傳值屬性,并且聲明單例類便利構(gòu)造器苍柏。
@interface Singleton : NSObject
@property (nonatomic, strong) NSDictionary *userInfo; /**< 單例屬性 */
+ (instancetype)defaultSingleton; /**< 單例便利構(gòu)造器 */
@end
steps 3:在Singleton.m文件中實(shí)現(xiàn)遍歷構(gòu)造器方法尼斧。
#import "Singleton.h"
static Singleton *singleton = nil;
@implementation Singleton
+ (instancetype)defaultSingleton {
// GCD創(chuàng)建單例,效率更高试吁,性能更好棺棵,消耗更低。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[Singleton alloc] init];
});
return singleton;
}
@end
steps 4:在HomeViewController.m文件中獲取單例實(shí)例熄捍,并且賦值單例屬性烛恤,賦值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 單例屬性賦值
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取單例實(shí)例余耽,首先需導(dǎo)入Singleton.h
Singleton *singleton = [Singleton defaultSingleton];
// 單例屬性賦值
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
singleton.userInfo = userInfo;
}
steps 5:在DetailViewController.m文件中獲取單例屬性缚柏,取值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 獲取單例屬性
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取單例實(shí)例碟贾,首先需導(dǎo)入Singleton.h
Singleton *singleton = [Singleton defaultSingleton];
// 獲取單例屬性值
NSLog(@"%@", singleton.userInfo);
}
steps 1:在HomeViewController.m中獲取NSUserDefaults實(shí)例袱耽,并且存值杀餐。
- (void)saveValueInUserDefaults {
// 獲取NSUserDefaults實(shí)例
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 存值
NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
[defaults setObject:userInfo forKey:@"userInfo"];
// 同步數(shù)據(jù)
[defaults synchronize];
}
steps 2:在DetailViewController.m中獲取值
- (void)getValueInUserDefaults {
// 獲取NSUserDefaults實(shí)例
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 根據(jù)key獲取值
NSDictionary *userInfo = [defaults objectForKey:@"userInfo"];
NSLog(@"%@", userInfo);
}