iOS 观察者模式以及代理的例子

1.KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模式的一种应用。我的看法是,这种模式有利于两个类间的解耦合,尤其是对于业务逻辑与视图控制 这两个功能的解耦合。

观察者模式中的kvo例子:(其中label、button是在xib文件中拖拽的,请大家注意)

Walker.h

#import <Foundation/Foundation.h>


@interface Walker : NSObject

{

    NSInteger age;

    NSString *name;

}

@property (nonatomic, assign)NSInteger age;

@property (nonatomic, retain) NSString *name;

- (id)initWithName: (NSString*)aName age: (NSInteger)aAge;

@end

Walker.m

#import "Walker.h"


@implementation Walker

@synthesize name,age;

- (id)initWithName:(NSString *)aName age:(NSInteger)aAge

{

    if (self = [super init]) {

        name = aName;

        age = aAge;

    }

    return self;

}

@end

ViewController.h

@interface ViewController : UIViewController

{

    Walker *walker;

}

@property (nonatomic, retain) Walker *walker;


@end

ViewController.m

#import "ViewController.h"

#import "Walker.h"


@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *age;

@property (weak, nonatomic) IBOutlet UIButton *plus;

- (IBAction)plusAction:(id)sender;


@end


@implementation ViewController

@synthesize age,plus;

@synthesize walker;


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    walker = [[Walker alloc]initWithName:@"李华" age:20];

    age.text = [NSString stringWithFormat:@"%ld",(long)walker.age];

    [walker addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:NULL];

    

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (IBAction)plusAction:(id)sender {

    walker.age +=2;

    NSLog(@"%ld",(long)walker.age);

}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    if ([keyPath isEqualToString:@"age"] && object == walker)

    {

        age.text = [NSString stringWithFormat:@"%ld",(long)walker.age];

    }

}

@end


2.通知:通知中心实际上是在程序内部提供了消息广播的一种机制。通知中心不能在进程间进行通信。实际上就是一个二传手,把接收到的消息,根据内部的一个消息转发表,来将消息转发给需要的对象。通知中心是基于观察者模式的,它允许注册、删除观察者。

观察者模式中的通知例子:首先我是讲ViewController设为navigationController,然后在上面拖拽了一个button和label。具体代码如下

Viewcontroller.m

#import "ViewController.h"

#import "NewViewController.h"


@interface ViewController ()

- (IBAction)next:(id)sender;

@property (weak, nonatomic) IBOutlet UILabel *label;


@end


@implementation ViewController

@synthesize label;



- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib

    

    //添加监听者

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

}


- (void)update:(NSNotification*)notification{

    

    id text = notification.object;

    label.text = text;

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (IBAction)next:(id)sender {

    NewViewController *new = [[NewViewController alloc]init];

    [self.navigationController pushViewController:new animated:YES];

}

@end


NewViewController.m

#import "NewViewController.h"


@interface NewViewController ()<UITextFieldDelegate>

@property (nonatomic, retain)UITextField *myTextField;


@end


@implementation NewViewController

@synthesize myTextField;


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    myTextField = [[UITextField alloc]init];

    myTextField.frame = CGRectMake(50, 300, 200, 60);

    myTextField.backgroundColor = [UIColor grayColor];

    myTextField.delegate = self;

    [self.view addSubview:myTextField];

    

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    btn.frame = CGRectMake(30, 400, 300, 60);

    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [btn setTitle:@"输入完成" forState:UIControlStateNormal];

    [self.view addSubview:btn];

    

    

    self.view.backgroundColor = [UIColor whiteColor];

    

//    //点击背景空白处键盘消失3


//    self.view.userInteractionEnabled = YES;

//    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(keyboardHide:)];

//    [self.view addGestureRecognizer:tapGestureRecognizer];


    

}

- (void)btnClick:(id)sender

{

    

     [[ NSNotificationCenter  defaultCenter] postNotificationName:@"subjectMessage" object:myTextField.text];

     [self.navigationController popToRootViewControllerAnimated:YES];

}

//键盘消失方法1

- (BOOL)textFieldShouldReturn:(UITextField *)textField

{

    return [textField resignFirstResponder];

}


//键盘消失方法2

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [self.myTextField resignFirstResponder];

}


键盘消失方法3*重点背景色射程除了黑色以外别的颜色

//-(void)keyboardHide:(UITapGestureRecognizer*)tap{

//    [myTextField resignFirstResponder];

//}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


@end

3.代理:意译一下就是:代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另外一个对象和程序中其他的对象进行交互。 主对象(这里指的是delegating object)中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一个事件。这个代理可以通过更新自己或是其它对象的UI界面或是其它状态来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其它即将发生的事件该如何来处理。代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。
具体代码如下:首先将viewcontroller设为navigationcontroller
ViewController.h

#import "ViewController.h"

#import "newViewController.h"


@interface ViewController ()<newViewConteollerDelegate>


@property (nonatomic, retain) UILabel *label;


@end


@implementation ViewController

@synthesize label;


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    label = [[UILabel alloc]initWithFrame:CGRectMake(40, 100, 300, 50)];\

    label.text = @"sad";

    label.tintColor = [UIColor redColor];

    [self.view addSubview:label];

    

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

    [btn setTitle:@"下一页" forState:UIControlStateNormal];

    btn.frame = CGRectMake(40, 240, 80, 40);

    btn.backgroundColor = [UIColor redColor];

    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


-(void)btnClick:(id)sender

{

    newViewController *new = [[newViewController alloc]init];

//    new.delegate = self;//代理

    

    //block

    new.newViewControllerBlock = ^(NSString *tfText)

    {

        self.label.text = tfText;

    };

    [self.navigationController pushViewController:new animated:YES];

}


#pragma -------newViewConteollerDelegate Method-------

-(void)passTextValue : (NSString *) textStr

{

    self.label.text = textStr;

}

@end

#import <UIKit/UIKit.h>

@protocol newViewConteollerDelegate <NSObject>

-(void)passTextValue : (NSString *) textStr;

@end

newViewController.h

@interface newViewController : UIViewController


@property (nonatomic, assign) id<newViewConteollerDelegate> delegate;

@property (nonatomic ,copy) void (^newViewControllerBlock) (NSString *tfText);


@end

newViewController.m

#import "newViewController.h"


@interface newViewController ()

@property (weak, nonatomic) IBOutlet UITextField *textField;

- (IBAction)backToViewController:(id)sender;


@end


@implementation newViewController

@synthesize delegate,textField;

@synthesize newViewControllerBlock;


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.

    

    

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (IBAction)backToViewController:(id)sender {

    

    //代理

//    if (delegate && [self.delegate respondsToSelector:@selector(passTextValue:)]) {

//        [self.delegate passTextValue:self.textField.text];

//    }

    

    //block

    if (self.newViewControllerBlock) {

        self.newViewControllerBlock(self.textField.text);

    }

    

    [self.navigationController popViewControllerAnimated:YES];

}

@end


4.block: blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。
具体代码是上面代理的红色字迹部分。功能和代理很像,上面的例子可以方便大家进行对比

参考网址:http://www.cnblogs.com/wengzilin/p/3223770.html






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值