IOS中消息传递的8种方式
来源:互联网 发布:石家庄程序员工资 编辑:程序博客网 时间:2024/06/06 15:45
原创Blog,转载请注明出处
blog.csdn.net/hello_hwc
一 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的数字加一
- (IBAction)up:(id)sender { NSInteger lastNum = self.label.text.integerValue; lastNum++; self.label.text = [NSString stringWithFormat:@"%ld",lastNum];}
Down Button使用方式二,用代码添加
定义如下函数,来处理Down Button点击事件
-(void)down:(id)sender{ NSInteger lastNum = self.label.text.integerValue; lastNum--; self.label.text = [NSString stringWithFormat:@"%ld",lastNum];}然后,在ViewDidLoad函数中,用代码绑定target-action
[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的数据源,解耦合的方式)
首先定义Protocol和DataSource,以及响应完成的Block类型(typedef定义)
<pre name="code" class="objc">
//// CustomAnimationView.h#import <UIKit/UIKit.h>@class CustomAnimationView;typedef void(^AnimationFinishedBlock)();@protocol CustomAnimationViewDataSource <NSObject>-(NSTimeInterval)animationDuration;-(CGPoint)AnimateToPoint;@end@protocol CustomAnimationViewDelegate <NSObject>@optional-(void)willStartAnimate:(CustomAnimationView *)view;-(void)didFinishedAnimate:(CustomAnimationView *)view;@end
然后,在CustomAnimationView的接口里定义
</pre><pre name="code" class="objc"><pre name="code" class="objc">@interface CustomAnimationView : UIView@property (weak,nonatomic) id<CustomAnimationViewDataSource>datasource;@property (weak,nonatomic) id<CustomAnimationViewDelegate>delegate;@property (copy,nonatomic) AnimationFinishedBlock completeBlock;@end最后,Button的事件中进行事件传递,
-(void)animate:(id)sender{ if (self.datasource == nil || CGPointEqualToPoint(self.circleView.center, [self.datasource AnimateToPoint])){ return; } if ([self.delegate respondsToSelector:@selector(willStartAnimate:)]) { [self.delegate willStartAnimate:self]; } [UIView animateWithDuration:[self.datasource animationDuration] animations:^{ self.circleView.center = [self.datasource AnimateToPoint]; } completion:^(BOOL finished) { if ([self.delegate respondsToSelector:@selector(didFinishedAnimate:)]) { [self.delegate didFinishedAnimate:self]; } if (self.completeBlock) { self.completeBlock(); } }];}
然后在SecondViewController中,让SecondViewController遵循Delegate和DataSource,提供DataSource所需的必要方法,提供Delegate的方法
<pre name="code" class="objc">@interface SecondViewController ()<CustomAnimationViewDataSource,CustomAnimationViewDelegate>@property (weak, nonatomic) IBOutlet CustomAnimationView *customview;@end@implementation SecondViewController- (void)viewDidLoad { [super viewDidLoad]; self.customview.delegate = self; self.customview.datasource = self; self.customview.completeBlock = ^(){ NSLog(@"Got finished action from block"); }; } // Do any additional setup after loading the view.-(NSTimeInterval)animationDuration{ return 1.0;}-(CGPoint)AnimateToPoint{ return CGPointMake(200, 400);}-(void)willStartAnimate:(CustomAnimationView *)view{ NSLog(@"will start");}-(void)didFinishedAnimate:(CustomAnimationView *)view{ NSLog(@"did finished");}
这样,点击的时候,就会按照DataSource提供的动画时间和动画的结束点来运行,并且可以在Log中,看到监听事件成功。
2015-01-29 20:29:06.582 MessageTransitionExample[3355:117440] will start2015-01-29 20:29:07.584 MessageTransitionExample[3355:117440] did finished2015-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注册监听的属性
[self.firstView addObserver:self forKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionNew context:(void*)&PrivateKVOContext];然后,在如下方法中监听变化,
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if (context == &PrivateKVOContext){ NSLog(@"first view backgroud color changed from KVO"); NSLog(@"%@",change.description); }}这里的context
static const int PrivateKVOContext = 0;
7 Notification(盲通信,用处也比较广泛)
在RandomChangeColorView的响应事件中,进行广播
[[NSNotificationCenter defaultCenter] postNotificationName:KRANDOMCHANGECOLORVIEWNOTIFICATION object:randomColor];然后,在ThridViewController中监听广播
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(colorChange:) name:KRANDOMCHANGECOLORVIEWNOTIFICATION object:nil];<pre name="code" class="objc">-(void)colorChange:(NSNotification *)notificaiton{ NSLog(@"Color chagne from notification"); NSLog(@"%@",notificaiton.object);}
这里的KRNADOMCHANGECOLORNOTIFICATION是一个宏定义的NSString
注意,注册KVO和通知都应该在合理的位置取消注册
-(void)viewWillDisappear:(BOOL)animated{ [self.firstView removeObserver:self forKeyPath:@"backgroundColor"]; [[NSNotificationCenter defaultCenter] removeObserver:KRANDOMCHANGECOLORVIEWNOTIFICATION];}
点击第三个ViewController的两个View,在Log中看到了监听成功
2015-01-29 20:31:07.675 MessageTransitionExample[3355:117440] first view backgroud color changed from KVO2015-01-29 20:31:07.676 MessageTransitionExample[3355:117440] { kind = 1; new = "UIDeviceRGBColorSpace 0.00784314 0.247059 0.168627 1";}2015-01-29 20:31:10.731 MessageTransitionExample[3355:117440] Color chagne from notification2015-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
- IOS中消息传递的8种方式
- IOS中消息传递的8种方式
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- iOS中消息的传递机制
- ICMP为什么没有用端口
- javase简单入门8 方法重写,final,静态块
- 字典树 SDUT OJ 2828
- BZOJ 1443 JSOI 2009 游戏Game 二分图+博弈
- Messgaebox线程堵塞
- IOS中消息传递的8种方式
- UVa: 1595 - Symmetry
- UVa 1312 - Cricket Field (高效枚举)
- Android 中从res/values/strings.xml中读取具体的字符串的方法
- canvas.save() canvas.restore() 作用
- javase简单入门9 抽象类,接口,小结
- 并发编程6-执行器
- struts2种出现的There is no Action mapped for namespace [/] and action name 错误
- 一切成功源于积累——20150129 1月27日 1月29日 1月30日 美瑞1H连续上涨盘