设计模式总结(上)

来源:互联网 发布:wp7.8软件下载 编辑:程序博客网 时间:2024/06/10 23:52
在做ios程序时,我们经常会用到各种设计模式,在这里,自己对其进行了一些总结,如果与您的理解有差异或者错误的地方,还望各位看官看后给予指正!

一、KVO/KVC
KVO(NSKeyValueObserving)"键-值-监听"定义了这样一种机制,当对象的属性值发生变化的时候,我们能收到一个通知。
KVC(NSKeyValueCoding)“键-值-编码”是一种间接访问对象属性的机制,而不是直接通过调用设置器访问器方法或者点语法去访问对象的属性。
NSObject类为所有对象提供了一个自动观测能力的NSKeyValueObserving协议。你可以根据具体需要来打开这个监听机制,KVO是基于KVC来实现的。
获取属性值时可以通过valueForKey:的方法,设置属性值用:setValue:forKey:。需要注意的是KVC中的value必须是对象。

监听通常遵循如下流程:
(1)、注册。下面方法中,keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据。

-(void)addObserver:(NSObject *)observer

      forKeyPath:(NSString*)keyPath

         options:(NSKeyValueObservingOptions)options

         context:(void *)context

其中,options是监听的选项,也就是说明监听返回的字典包含什么值。有两个常用的选项:

 NSKeyValueObservingOptionNew指返回的字典包含新值。

 NSKeyValueObservingOptionOld指返回的字典包含旧值。

context是一个任意类型的指针。

(2)、实现监听方法。

 

-(void)observeValueForKeyPath:(NSString *)keyPath

                 ofObject:(id)object

                   change:(NSDictionary *)change

                  context:(void*)context

其中,change里存储了一些变化的数据,比如变化前的数据,变化后的数据。

KVO是键值-监听,我们用它来监听KVC值的变化。
增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者。
[selfremoveObserver:self forKeyPath:@"name"];

二、目标事件 

Target-action 设计模式


目标事件的设计模式使用非常广泛,下面是我认为总结的比较好的,所以就转过来用了。大家可以看一下。


其实Target-action模式很简单,就是当某个事件发生时,调用那个对象中的那个方法。如:按下按钮时,调用Controller里边的click方法。“那个对象”就是Target,“那个方法”就是Action,及Controller是Targer,click方法是action。

一般Target都是Controller,而Action有它自己固有的格式:-(IBAction)click:(id)sender。

如下图所示,target是处理交互事件的对象实例,action是target对象中处理该事件的方法。

这里有两种方式给“炒菜”按钮设置Action:

1、直接拖拽连线

2、以代码的方式实现

在iOS中有一个UIControl类,该类中定义了一个

-(void)addTarget:(id)target action:(SEL) forControlEvents:(UIControlEvents)controlEvents

 

 方法,大部分视图类都继承自UIControl类,所以"炒菜"按钮可以使用该方法实现Target-action模式。在iOS中这种设计模式被称作一个对象给另外一个对象发送消息。

- (void)viewDidLoad{    [super viewDidLoad];        // 给炒菜按钮添加点击事件    // 使用Target-action设计模式,在两个对象间直接发送消息    [self.btnCooking addTarget:self action:@selector(pressCooking:) forControlEvents:UIControlEventTouchUpInside];}

1、self 指目标对象为当前对象,及WViewController;

2、action 即 在目标对象上的点击方法;

3、何时调用该方法,UIControlEventTouchUpInside即单击时。

“炒菜”按钮是一个可交互的视图控件,点击它后,它指定了一个target(目标对象),并执行目标对象上指定的action(方法)。

action方法有以下几种形式:

- (void)doSomething;// OR- (void)doSomething:(id)sender;// OR- (IBAction)doSomething:(id)sender;// OR- (IBAction)doSomething:(UIButton *) sender;

这里的sender,发送者,就是对 “菜单” 按钮对象的引用。

以下代码是完全用代码定义的一个UIButton,并添加在self.view中:

- (void)viewDidLoad{    [super viewDidLoad];        // 实例化按钮,并设置按钮类型为圆角    UIButton *btnCustom = [UIButton buttonWithType:UIButtonTypeRoundedRect];    // 设置按钮大小    btnCustom.frame = CGRectMake(124, 140, 73, 44);    // 设置按钮标题    [btnCustom setTitle:@"点击我..." forState:UIControlStateNormal];    // 设置按钮点击事件    [btnCustom addTarget:self action:@selector(customButton) forControlEvents:UIControlEventTouchUpInside];    // 将按钮添加到View    [self.view addSubview:btnCustom];}- (void)customButton{    [self.lblDish setText:self.txtMaterial.text];}

 UIButton的几种触发方式:

1、UIControlEventTouchDown 

  指鼠标左键按下(注:只是“按下”)的动作

2、UIControlEventTouchDownRepeat

  指鼠标左键连续多次重复按下(注:只是“按下”)的动作,比如,鼠标连续双击、三击、……、多次连击。

  说明:多次重复按下时,事件序列是这样的:

  UIControlEventTouchDown -> 

  (UIControlEventTouchUpInside) -> 

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) -> 

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) ->

  ......

  除了第一次按下外,后面每次摁下都是一个UIControlEventTouchDown事件,然后紧跟一个UIControlEventTouchDownRepeat事件。

3、UIControlEventTouchDragInside

  指按下鼠标,然后在控件边界范围内拖动。

4、UIControlEventTouchDragOutside

  与UIControlEventTouchDragInside不同的是,拖动时,鼠标位于控件边界范围之外。

  但首先得有个UIControlEventTouchDown事件,然后接一个UIControlEventTouchDragInside事件,再接一个UIControlEventTouchDragExit事件,这时,鼠标已经位于控件外了,继续拖动就是UIControlEventTouchDragOutside事件了。

  具体操作是:在控件里面按下鼠标,然后拖动到控件之外。

5、UIControlEventTouchDragEnter

  指拖动动作中,从控件边界外到内时产生的事件。

6、UIControlEventTouchDragExit

  指拖动动作中,从控件边界内到外时产生的事件。

7、UIControlEventTouchUpInside

  指鼠标在控件范围内抬起,前提先得按下,即UIControlEventTouchDown或UIControlEventTouchDownRepeat事件。

8、UIControlEventTouchUpOutside

  指鼠标在控件边界范围外抬起,前提先得按下,然后拖动到控件外,即 

  UIControlEventTouchDown -> 

  UIControlEventTouchDragInside(n 个) -> 

  UIControlEventTouchDragExit -> 

  UIControlEventTouchDragOutside(n 个) 

  时间序列,再然后就是抬起鼠标,产生UIControlEventTouchUpOutside事件。


三、协议和代理设计模式
协议:是一系列方法的集合,根据配置,遵守该协议的类会去实现这个协议中规定的若干个方法。
协议分为非正式协议和正式协议,从写法上的区别在于非正式协议使用@interface来定义的,而正式协议是用@protocol来定义的。
协议的说明:
(1)协议声明了可以被任何类实现的方法。
(2)协议不是类,他是定义了一个其他对象可以实现的接口。
(3)如果在某个类中实现了协议中的某个方法,也就是这个类实现了那个协议。
(4)协议经常用来实现委托对象,一个委托对象是一种用来协同或者代表其他对象的特殊对象
(5)新特性说明
@optional预编译指令:表示可以选择实现的方法。
@required预编译指令:表示必须强制实现的方法。

定义协议时,可以通过@required与@optional来配置遵守这个协议必须去实现的方法和可以选择的方法。譬如:
@protocolMyChooseDayViewDelegate<NSObject>  
@required  
-returnChooseDay:(id)myChooseDayView;  
@optional  
-hideThisView;  
-changeDateFormatter:(NSString*)formatString;  
@end  


@protocol MyChooseTimeViewDelegate<MyChooseDayViewDelegate>  
- doSomething; 
@end  
MyChooseTimeViewDelegate扩展了MyChooseDayViewDelegate这个协议,也就是说,假如遵守了MyChooseTimeViewDelegate的话,也必须实现MyChooseDayViewDelegate中的方法(@required)使用分类的话,就是在定义类的头文件中使用<>将所需要的协议引入,如果引入多个协议,用","分隔,譬如:

@interface MyClassView:UIViewController<MyChooseDayViewDelegate,UIAlertViewDelegate>  
//TODO:balabalabala...  
@end  

想要检查某个类是否实现了某个协议或者某个类是否实现了某个协议的方法,可以通过以下方式来进行测试

//获取某个对象  
MyClassView *myClassView =xxxxxxx;  
//判断该对象是否实现了MyChooseDayViewDelegate协议  
if([myClassView conformToProtocol:@protocol(MyChooseDayViewDelegate)]){  
//TODO:balabalabala...  
 
//判断对象是否实现了某个方法就用我们经常会使用到的  
if([myClassViewresponseToSelector:@selector(xxxx)]){  
//TODO:balabalabala...  
}  


代理:它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。这个时候,这位其他人就是我的代理。

代理在iOS开发会被经常使用,而且代理的使用往往配合着协议。我重复一次我对他的理解,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。
举例来说,我在办公室里正在写代码,突然发现口很渴像喝瓶冰百事,但下楼是件麻烦的事情,我不愿意下楼。这个时候我想起小卖部可以商品加价2元就外送到家服务,我就打电话给小卖部,委托小卖部给我送一瓶水上来。这个时候,小卖部就是我的代理,我委托他帮买水并送上来。这个例子中小卖部是我的代理,商品加价2元外送到家服务就是商品买卖协议(这个叫法肯定不是最佳的,姑且这么叫吧)中的一个方法。
不要觉得麻烦,我们再最后理一遍,小卖部遵守商品买卖协议,我让小卖部成为了我的代理,代替我完成了买瓶冰百事的事情。
以iOS开发的角度来说,UIViewController想使用一个tableview,需要遵守UITableviewDataSource,UITableViewDelegate这2个协议,同时设置tableview的代理为自身,才可以完整的实现Table。

(未完待续。。。)





0 0
原创粉丝点击