你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> IOS中消息傳遞的8種方式

IOS中消息傳遞的8種方式

編輯:關於IOS

一 MVC簡介

MVC是將應用中的類組織起來的一種策略。是IOS開發最常用的設計模式,當然,還有諸如MVVM,VIPER等模式,不過不在本文的討論范疇。

MVC代表什麼:Model-View-Controller。

Model:應用是什麼(what the app is )

Controller:如何呈現Model

View:你看到的東西

注意:

1.Controller可以直接訪問Model和View。

2.Model和View不要直接通信。

3.View和Model是不依賴於Controller的,這是最基本的,不然你的工程在測試和維護起來都非常麻煩。

二 消息傳遞的8種方式

為了更好的理解消息傳遞,我寫了個簡單的demo,三個ViewController分別展示不同的消息傳遞方式。

第一個ViewController如圖

Up,Down兩個Button點擊後分別會將Label的數字加減一

1 Outlet(Controller訪問View)

注意:Outlet應當是weak的,因為強Outlet不應該參與引用計數。

使用Outlet非常簡單,

在storyboard上拖出一個控件,然後control+drag拖出一個outlet,如圖沿著紅線拖拽


不要忘記給ViewController設定為自定義的類,不然打開輔助編輯界面不會無法拖拽。

這樣,就可以用屬性的訪問方式來直接訪問label

2 target Action(盲通信,View反饋給Controller)

Up Button使用方式一,在storyboard上拖拽


然後在自動創建方法種進行如下定義,這個方法負責將label的數字加一

[objc] view plaincopy

  1. - (IBAction)up:(id)sender {
  2.     NSInteger lastNum = self.label.text.integerValue;
  3.     lastNum++;
  4.     self.label.text = [NSString stringWithFormat:@"%ld",lastNum];
  5. }

 

Down Button使用方式二,用代碼添加

定義如下函數,來處理Down Button點擊事件

[objc] view plaincopy

  1. -(void)down:(id)sender{
  2.     NSInteger lastNum = self.label.text.integerValue;
  3.     lastNum--;
  4.     self.label.text = [NSString stringWithFormat:@"%ld",lastNum];
  5. }

然後,在ViewDidLoad函數中,用代碼綁定target-action

[objc] view plaincopy

  1. [self.downButton addTarget:self action:@selector(down:) forControlEvents:UIControlEventTouchUpInside];

 

第二個ViewController很簡單,就是在Storyboard上拖出一個View,並把類選擇為我自定義的一個類CustomAnimateView,這個類裡實現了用代理,block,DataSource。

點擊Animate按鈕,紅色的原點會移動到SecondViewController提供位置,移動的時間由DataSource提供,移動開始和結束的事件由Delegate來提供,移動結束的事件同時也由Block提供。

3 Delegate (View傳遞事件給Controller,也用用來Controller傳遞數據,用處比較廣泛,解耦合)

4 DataSource (View的數據源,解耦合的方式)

5 Block(常常用來傳遞事件)  

首先定義Protocol和DataSource,以及響應完成的Block類型(typedef定義)

[objc] view plaincopy

  1. <pre name="code" class="objc">
[objc] view plaincopy

  1. //
  2. //  CustomAnimationView.h
  3. #import <UIKit/UIKit.h>
  4. @class CustomAnimationView;
  5. typedef void(^AnimationFinishedBlock)();
  6. @protocol CustomAnimationViewDataSource <NSObject>
  7. -(NSTimeInterval)animationDuration;
  8. -(CGPoint)AnimateToPoint;
  9. @end
  10. @protocol CustomAnimationViewDelegate <NSObject>
  11. @optional
  12. -(void)willStartAnimate:(CustomAnimationView *)view;
  13. -(void)didFinishedAnimate:(CustomAnimationView *)view;
  14. @end

 



然後,在CustomAnimationView的接口裡定義

[objc] view plaincopy

  1. </pre><pre name="code" class="objc"><pre name="code" class="objc">@interface CustomAnimationView : UIView
  2. @property (weak,nonatomic) id<CustomAnimationViewDataSource>datasource;
  3. @property (weak,nonatomic) id<CustomAnimationViewDelegate>delegate;
  4. @property (copy,nonatomic) AnimationFinishedBlock completeBlock;
  5. @end


最後,Button的事件中進行事件傳遞,

[objc] view plaincopy

  1. -(void)animate:(id)sender{
  2.     if (self.datasource == nil || CGPointEqualToPoint(self.circleView.center, [self.datasource AnimateToPoint])){
  3.         return;
  4.     }
  5.     if ([self.delegate respondsToSelector:@selector(willStartAnimate:)]) {
  6.         [self.delegate willStartAnimate:self];
  7.     }
  8.     [UIView animateWithDuration:[self.datasource animationDuration]
  9.                      animations:^{
  10.                          self.circleView.center = [self.datasource AnimateToPoint];
  11.                      }
  12.                      completion:^(BOOL finished) {
  13.                          if ([self.delegate respondsToSelector:@selector(didFinishedAnimate:)]) {
  14.                              [self.delegate didFinishedAnimate:self];
  15.                          }
  16.                          if (self.completeBlock) {
  17.                              self.completeBlock();
  18.                          }
  19.                      }];
  20. }

然後在SecondViewController中,讓SecondViewController遵循Delegate和DataSource,提供DataSource所需的必要方法,提供Delegate的方法

[objc] view plaincopy

  1. <pre name="code" class="objc">@interface SecondViewController ()<CustomAnimationViewDataSource,CustomAnimationViewDelegate>
  2. @property (weak, nonatomic) IBOutlet CustomAnimationView *customview;
  3. @end
  4. @implementation SecondViewController
  5. - (void)viewDidLoad {
  6.     [super viewDidLoad];
  7.     self.customview.delegate = self;
  8.     self.customview.datasource = self;
  9.     self.customview.completeBlock = ^(){
  10.         NSLog(@"Got finished action from block");
  11.     };
  12. }
  13.     // Do any additional setup after loading the view.
  14. -(NSTimeInterval)animationDuration{
  15.     return 1.0;
  16. }
  17. -(CGPoint)AnimateToPoint{
  18.     return CGPointMake(200, 400);
  19. }
  20. -(void)willStartAnimate:(CustomAnimationView *)view{
  21.     NSLog(@"will start");
  22. }
  23. -(void)didFinishedAnimate:(CustomAnimationView *)view{
  24.     NSLog(@"did finished");
  25. }

 



這樣,點擊的時候,就會按照DataSource提供的動畫時間和動畫的結束點來運行,並且可以在Log中,看到監聽事件成功。

[objc] view plaincopy

  1. 2015-01-29 20:29:06.582 MessageTransitionExample[3355:117440] will start
  2. 2015-01-29 20:29:07.584 MessageTransitionExample[3355:117440] did finished
  3. 2015-01-29 20:29:07.585 MessageTransitionExample[3355:117440] Got finished action from block

第三個ViewController如圖,兩個View(自定義的RandomChangeColorView)各添加了點擊的手勢,點擊的時候,隨機更改自己的backgroundColor,然後,第一個View由KVO的方式監聽變化,第二個View用Notificaition的方式來監聽變化


6 KVO(Model反饋給View)

在ThridViewController注冊監聽的屬性

[objc] view plaincopy

  1. [self.firstView addObserver:self forKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionNew context:(void*)&PrivateKVOContext];

然後,在如下方法中監聽變化,

[objc] view plaincopy

  1. -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context{
  2.     if (context == &PrivateKVOContext){
  3.         NSLog(@"first view backgroud color changed from KVO");
  4.         NSLog(@"%@",change.description);
  5.     }
  6. }

這裡的context

[objc] view plaincopy

  1. static const int PrivateKVOContext = 0;

7 Notification(盲通信,用處也比較廣泛)

在RandomChangeColorView的響應事件中,進行廣播

[objc] view plaincopy

  1. [[NSNotificationCenter defaultCenter] postNotificationName:KRANDOMCHANGECOLORVIEWNOTIFICATION object:randomColor];

然後,在ThridViewController中監聽廣播

[objc] view plaincopy

  1. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(colorChange:) name:KRANDOMCHANGECOLORVIEWNOTIFICATION object:nil];<pre name="code" class="objc">-(void)colorChange:(NSNotification *)notificaiton{
  2.     NSLog(@"Color chagne from notification");
  3.     NSLog(@"%@",notificaiton.object);
  4. }

 



這裡的KRNADOMCHANGECOLORNOTIFICATION是一個宏定義的NSString

注意,注冊KVO和通知都應該在合理的位置取消注冊

[objc] view plaincopy

  1. -(void)viewWillDisappear:(BOOL)animated{
  2.     [self.firstView removeObserver:self forKeyPath:@"backgroundColor"];
  3.     [[NSNotificationCenter defaultCenter] removeObserver:KRANDOMCHANGECOLORVIEWNOTIFICATION];
  4. }

 

點擊第三個ViewController的兩個View,在Log中看到了監聽成功

[objc] view plaincopy

  1. 2015-01-29 20:31:07.675 MessageTransitionExample[3355:117440] first view backgroud color changed from KVO
  2. 2015-01-29 20:31:07.676 MessageTransitionExample[3355:117440] {
  3.     kind = 1;
  4.     new = "UIDeviceRGBColorSpace 0.00784314 0.247059 0.168627 1";
  5. }
  6. 2015-01-29 20:31:10.731 MessageTransitionExample[3355:117440] Color chagne from notification
  7. 2015-01-29 20:31:10.731 MessageTransitionExample[3355:117440] UIDeviceRGBColorSpace 0.388235 0.482353 0.835294 1

 

8 Segue在ViewController切換的時候,常常用來傳遞信息

之前的幾篇文章,我詳細介紹了各種,segue,並且附上了demo。

嵌入式Segue

自定義Segue

Modal Segue和Unwind Segue

三 最後說說代理和Notification的區別

  代理就像打電話,只有先接通了才能進行信息交流。而Notification就像是廣播,你收聽不收聽,多少個人收聽跟我沒關系,反正我要廣播,但是注意,你跟廣播站注冊了你要收聽廣播,但是你不收聽了卻不提前告訴廣播站。下次廣播站發現有通知要給你,你卻不知道哪去了,你就要遭殃了(App 有可能會崩潰)。

最後,附上整個Demo的下載鏈接。

CSDN鏈接

http://download.csdn.net/detail/hello_hwc/8408187

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved