iOS学习笔记—11 常见设计模式

一.委托

1.协议和委托的关系

   协议就相当于是C++中的纯虚基类,它只能定义函数并且只能由其他类来实现。而委托则类似于Java接口,其实协议和委托之间并无必然联系,只是在Obj—C中常用协议来实现委托。

        protocol-协议,就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现。

        delegate-委托,顾名思义就是委托别人办事,就是当一件事情发生后,自己不处理,让别人来处理。

        注意以下几点:

1.协议声明了可以被任何类实现的方法; 
2.协议不是类,它是定义了一个其他对象可以实现的接口 ;
3.如果在某个类中实现了协议中的某个方法,也就是这个类实现了那个协议。 
4.协议经常用来实现委托对象。

5.在协议的声明中的特性关键字:

      @optional预编译指令表示可以的方法 

      @required预编译指令表示必强制的方法 

     2.协议的用法

     下面举个例子来说明:当一个A view 里面包含了B view,而b view需要修改a view的界面,那么这个时候就需要用到委托了。

步骤如下:

1、首先定一个协议

2、a view实现协议中的方法

3、b view设置一个委托变量

4、把b view的委托变量设置成aview,意思就是,b view委托a view办事情。

5、事件发生后,用委托变量调用a view中的协议方法

具体实现时,代码可以类似于:

[plain]  view plain copy
  1. B_View.h:  
  2. @protocol  B_ViewDelegate<NSObject>  
  3. @optional   
  4. -(void)touch:(id)sender;  
  5. @end  
  6. @interface  B_View:UIViewController  
  7. {}  
  8. @property(nonatomic,retain) id<B_ViewDelegate> touchDelegate;//以一个别名来声明委托  
  9. @end  
  10. B_View.m:    
  11. @synthesize touchDelegate;    
  12. - (id)initWithFrame:(CGRect)frame {    
  13. if (self = [super initWithFrame:frame]) {    
  14.  [touchDelegate  touch];//调用协议委托,委托给A_View来实现函数  
  15. }    
  16. return self;    
  17. }    
  18. @end  
  19.   
  20. A_View.h:  
  21. @interface:UIViewController<B_ViewDelegate>  
  22. {  
  23. B_View *myB_View;  
  24. }  
  25. @end  
  26. A_View.m:  
  27. - (void)viewWillAppear:(BOOL)animated    
  28. {    
  29. myB_View.touchDelegate = self; //设置委托 ,这里可以看出委托其实也可以理解为B_View中的一个属性   
  30. [self.view addSubview: myB_View];    
  31. }    
  32. - (void)ontouch:(id)sender  
  33. {    
  34.    //实现协议方法 
  35.   view plcop 

3.委托的用法

        就像上面说的,其实协议和委托并无必然的联系,只是在Obj—C中我们时常用协议来实现委托,但是我们不用协议也可以实现委托。例如:

       定义一个类A:

[plain]  view plain copy
  1. @interface A:NSObject  
  2. -(void)print;  
  3. @end  
  4. @implement A  
  5. -(void)print  
  6. {  
  7. NSLog(“ok,print”);  
  8. }  

     定义一个类B,在B中声明A的实例为B的成员变量:

[plain]  view plain copy
  1. @interface B:NSObject  
  2. {  
  3.    A *a_delegate;  
  4. }  
  5. @end  

     然后在main()函数中实现委托机制:

[plain]  view plain copy
  1. void main  
  2. {  
  3. B *b=[[B alloc] init];    
  4. A *a=[[A alloc] init];    
  5. b.a_delegate=a; //设置b中的成员变量为a,这样就可以调用a中print方法。   
  6. [b.a_delegate print];    
  7. }  

      还有一种方式,这种方式接近于我们所用的协议实现委托机制,但它还并没有用到协议:

首先,定义一个类B,B委托类A来实现print:

[plain]  view plain copy
  1. @interface B:NSObject{    
  2. id delegate;  
  3. }    
  4. @end   
  5. @implement B    
  6.   
  7. -(void)callPrint{    
  8. [self.delegate print];    
  9. }    
  10. @end    

然后,在类A中实现print:

[plain]  view plain copy
  1. @interface A:NSObject{    
  2. B *b;    
  3. }    
  4. -(void)print;    
  5. @end    
  6. @implement A    
  7. -(void)viewDidLoad{    
  8. b=[[B alloc]init];    
  9. b.delegate=self;  //设置B的代理为self(即A)  
  10. }    
  11. -(void)print{    
  12. NSLog(@"print was called");    
  13. }  //在A中实现print  
  14. @end  
还有一点值得提一下

       数据源几乎等同于委托,不同之处在于它同发布委托的对象之间关系。发布委托的对象并不把对于用户界面的控制转交给它,而是把数据控制交给它。发布委托的对象,通常是诸如表视图这样的视图对象。它持有数据源引用,并时不时向其索要待显示数据。数据源和委托一样,也必须遵循某种协议并至少实现协议所要求的方法。数据源负责管理模型对象的内存,并将其提供给发布委托的视图。

二.单例

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

1.单例模式的要点:

显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

2.单例模式的优点:

1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例。  2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程 IOS中的单例模式  在objective-c中要实现一个单例类,至少需要做以下四个步骤:

1、为单例对象实现一个静态实例,并初始化,然后设置成nil,

2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,

3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,

4、适当实现allocWitheZone,copyWithZone,release和autorelease。下面以SurveyRunTimeData为例子: static SurveyRunTimeData *sharedObj = nil; //第一步:静态实例,并初始化。

  1. @implementation SurveyRunTimeData
  2. + (SurveyRunTimeData*) sharedInstance  //第二步:实例构造检查静态实例是否为nil
  3. {
  4.     @synchronized (self)
  5.     {
  6.         if (sharedObj == nil)
  7.         {
  8.             [[self alloc] init];
  9.         }
  10.     }
  11.     return sharedObj;
  12. }

  13. + (id) allocWithZone:(NSZone *)zone //第三步:重写allocWithZone方法
  14. {
  15.     @synchronized (self) {
  16.         if (sharedObj == nil) {
  17.             sharedObj = [super allocWithZone:zone];
  18.             return sharedObj;
  19.         }
  20.     }
  21.     return nil;
  22. }

  23. - (id) copyWithZone:(NSZone *)zone //第四步
  24. {
  25.     return self;
  26. }

  27. - (id) retain
  28. {
  29.     return self;
  30. }

  31. - (unsigned) retainCount
  32. {
  33.     return UINT_MAX;
  34. }

  35. - (oneway void) release
  36. {
  37.     
  38. }

  39. - (id) autorelease
  40. {
  41.     return self;
  42. }
  43. - (id)init
  44. {
  45.     @synchronized(self) {
  46.         [super init];//往往放一些要初始化的变量.
  47.         return self;
  48.     }
  49. }

  50. @end

三.通知

iOS软件开发的时候会遇到这种情况:打开APP后会在后台运行某个方法,例如下载文件,下载完成后可能需要调用某个方法来刷新界面,这时候可能没法在下载的函数中回调。NSNotificationCenter(通知)是一个很好的选择。

通知使用起来非常的简单:
1. 定义将要调用的方法:

- (void)callBack{
    NSLog(@"this is Notification.");
}

2. 定义通知:

[[NSNotificationCenter defaultCenter] addObserver: self
    selector: @selector(callBack)
    name: @"back"
    object: nil];

3. 调用通知:

- (void)getNotofocation{
    NSLog(@"get it.");
    //发出通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"back"object:self];
}
4. 移出通知:
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"back"object:nil];
    [super dealloc];
}

在调用通知的时候程序会在整个项目中寻找此通知的名称,找到后发出请求,因此通知的名称需要在整个项目中唯一。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值