廢話不多說,直接進入主題: 這裡要說的方式有6種:1、屬性傳值 2、block 3、delegate 4、UserDefault 5、單例 6、通知(篇幅原因我只寫核心代碼,如果看不懂可以直接在最下麵去github 看demo) 1、block(個人覺得最常用的場景下最好用的) 先說我最常用的blo ...
廢話不多說,直接進入主題:
這裡要說的方式有6種:1、屬性傳值 2、block 3、delegate 4、UserDefault 5、單例 6、通知(篇幅原因我只寫核心代碼,如果看不懂可以直接在最下麵去github 看demo)
1、block(個人覺得最常用的場景下最好用的)
先說我最常用的block吧,屬性傳值就很簡單了,主要用於順傳,我們在這裡包括下麵都主要講逆傳。屬性傳值放在block里一起寫了。
下麵上代碼:
1 //secondVc.h 2 typedef void (^TestBlock) (NSString *str); 3 4 @interface ATNextViewController : UIViewController 5 //定義block 6 @property (nonatomic, copy) TestBlock testBlock; 7 @end
1 //secondVc.m 2 - (void)btnClick:(UIButton *)btn { 3 if(self.testBlock) { //block傳值 4 self.testBlock(@"綠色"); 5 } 6 7 [self.navigationController popViewControllerAnimated:YES]; 8 }
下麵是第一個VC代碼:
//Vc.m - (void)btnClick:(UIButton *)btn { ATNextViewController *nextVc = [[ATNextViewController alloc] init]; nextVc.inStr = @"紅色"; //屬性傳值,用於順傳,直接傳就好了 //這裡是block回傳的值 nextVc.testBlock = ^(NSString *str) { NSLog(@"%@",str); }; [self.navigationController pushViewController:nextVc animated:YES]; }
2、delegate
代理要首先搞清楚誰傳值給誰,我這裡主要寫的都是逆傳,內層控制器傳向外層控制器,那也就是secondVc傳值給Vc,所以應該是Vc作為secondVc的代理,在代理方法接收secondVc傳過來的值。
secondVc的代碼:
1 //secondVc.h 2 3 //聲明代理 4 @protocol ATNextVcDelegate <NSObject> 5 6 @optional 7 - (void)inStr:(NSString *)inStr; 8 @end 9 @interface ATNextViewController : UIViewController 10 @property (nonatomic, weak) id<ATNextVcDelegate> delegate; 11 @end
1 //secondVc.m 2 //代理傳值 3 4 - (void)btnClick:(UIButton *)btn { 5 if ([self.delegate respondsToSelector:@selector(inStr:)]) { 6 [self.delegate inStr:@"紅色"]; 7 } 8 [self.navigationController popViewControllerAnimated:YES]; 9 }
Vc代碼:
1 //Vc.m 2 //代理方法接收值 3 4 - (void)btnClick:(UIButton *)btn { 5 ATNextViewController *nextVc = [[ATNextViewController alloc] init]; 6 nextVc.delegate = self; 7 [self.navigationController pushViewController:nextVc animated:YES]; 8 } 9 #pragma mark - ATNextVcDelegate 10 - (void)inStr:(NSString *)inStr { 11 NSLog(@"%@========", inStr); 12 }
3、UserDefault
這種方式會在本地存下文件,屬於數據持久化(關於數據持久化有時間會另開一篇詳細講解)的一種。再次打開程式依然會有上一次保存留下的值。
這裡只有存和取兩個動作:
1 //secondVc.m 2 - (void)btnClick:(UIButton *)btn { 3 //存 4 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 5 [defaults setObject:@"黃色" forKey:@"btnColor"]; 6 [defaults setObject:@"100x100" forKey:@"btnSize"]; 7 [defaults synchronize]; 8 9 [self.navigationController popViewControllerAnimated:YES]; 10 11 }
1 //Vc.m 2 3 - (void)viewWillAppear:(BOOL)animated { 4 [super viewWillAppear:animated]; 5 //取 6 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 7 NSString *btnColor = [defaults objectForKey:@"btnColor"]; 8 NSString *btnSize = [defaults objectForKey:@"btnSize"]; 9 NSLog(@"%@ %@",btnColor,btnSize); 10 }
和之前不同的是,這種方式只要進入這個界面就會取值,而不一定只是從上一個界面返回才傳值。
4、單例
單例一般直接做成巨集,用的時候拿過來直接用就好了,所以單例巨集文件這裡就不寫了,感興趣可以去demo看一下,直接上代碼:
這裡我定義了一個單例類,用它存用戶登錄狀態的信息,之後是控制器中的使用:
//ATLoginStatus.h #import <Foundation/Foundation.h> #import "ATSingleton.h" @interface ATLoginStatus : NSObject @property (nonatomic, assign) BOOL isLogin; @property (nonatomic, copy) NSString *phoneNumStr; SingletonH(LoginStatus) @end
// ATLoginStatus.m #import "ATLoginStatus.h" @implementation ATLoginStatus SingletonM(LoginStatus) @end
//secondVc.m - (void)btnClick:(UIButton *)btn { //存 ATLoginStatus *status = [ATLoginStatus sharedLoginStatus]; status.phoneNumStr = @"12345"; status.isLogin = YES; [self.navigationController popViewControllerAnimated:YES]; }
//Vc.m - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //取 ATLoginStatus *status = [ATLoginStatus sharedLoginStatus]; NSLog(@"%@ %d",status.phoneNumStr,status.isLogin); }
5、通知
通知主要是發通知和收通知兩部:
發通知:
1 //secondVc.m 2 3 - (void)btnClick:(UIButton *)btn { 4 //發出通知 5 [[NSNotificationCenter defaultCenter] postNotificationName:@"btnColorNoti" object:self userInfo:@{@"btnColor": @"黃色"}]; 6 [self.navigationController popViewControllerAnimated:NO]; 7 }
收通知:
//Vc.m - (void)viewDidLoad { [super viewDidLoad]; //... //註冊通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(btnColorNoti:) name:@"btnColorNoti" object:nil]; } //收到通知的時候調用這個方法接受到通知消息 - (void)btnColorNoti:(NSNotification *)noti { NSDictionary *dict = noti.userInfo; NSLog(@"%@",dict[@"btnColor"]); } //控制器銷毀的時候註銷通知監聽 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
OK,就是這些了,雖然這些方式都能用於控制器之間傳值,但是其實有些方式是沒有必要用在我舉例的這種普通場景(跑一下我的demo就明白這是什麼場景了)下的(當然屬性傳值只能用於順傳),在我所舉例的這種場景下,用block是最簡潔的,delegate也可以,但是個人感覺對於傳值來說過於麻煩了,通知也還可以,但還是不如block。但是單例和UserDefaults其實是不需要在這種場景下用的,他們可以用在兩個控制器隔很遠的情況下,或者兩個控制器沒有關聯的情況下。就像我舉的單例的例子中,存一下全局都可能用到的如用戶信息,這樣全局都能隨時取得這個信息。
下麵是demo:
my github:https://github.com/alan12138/somethingInteresting