码迷,mamicode.com
首页 > 其他好文 > 详细

OC教程9-开发模式

时间:2015-06-01 22:46:20      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:oc开发模式   单例模式   oc观察者模式   oc消息模式   

OC9-开发模式

本章内容主要讲述OC语言中常用的开发模式,开发模式是解决某些具体问题的固定解决方案。在OC中主要由三种可以使用

  • 单例模式
  • 键值观察模式
  • 消息模式

1,单例模式

在开发过程中,经常有一些共享型的数据需要储存在一个公共的地方,需要的时候,可以方便回去。单例模式便提供创建一个公共地方的方法。

@interface TestObj: NSObject

@property double a;

@end

例如我们声明上文中的一个对象,其中有一个a的属性可以存储数据。

TestObj * obj1 = [[TestObj alloc] init];
TestObj * obj2 = [[TestObj alloc] init];

obj1.a = 1;
obj2.a = 2;

上文中,通过两个对象指针访问a属性,是两块完全不同的内存空间,所有,两个对象储存的值也没有任何关联。但如果a是一个共享型的数据,那么在代码的任何地方获取的对象指针,应该都必须指向同一块内存,这样才能保证,通过任意对象指针获取的数据都是同一个数据。

解决以上问题,我们需要对类进行单例改造,添加一个单例方法,通过单例方法获取的对象指针都会指向全局唯一的内存。

@interface TestObj: NSObject

@property double a;

+(instancetype)shareTestObj;

@end

单例方法为加号方法,通常以share+类目的方式进行命名。

@implementation TestObj

+(instancetype)shareTestObj
{
    static TestObj * obj = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        obj = [[TestObj alloc] init];
    });

    return obj;
}
@end

单例方法的实现也十分简单,首先声明一个静态对象指针,保证这个对象指针不会被释放。然后调用GCD中的只运行一次的方法,确保在任何情况下只会开辟一块内存空间,然后将对象指针的值返回。

TestObj * obj1 = [TestObj shareTestObj];
TestObj * obj2 = [TestObj shareTestObj];

经过处理的类具有单例方法,通过单例方法获取的对象指针所指向的内存为同一块内存,这样,在任何一个地方,只需要调用单例方法,便可以获取共享数据。

2,键值观察模式

OC中提供一个键值观察的机制,让我们可以主动观察某一个对象的属性变化情况。

NSObject类支持键值观察机制,所有其子类创建的对象也同时支持。使用兼职观察需要两步

  • 注册观察者与观察路径
  • 实现观察者回调

注册观察者与观察路径为NSObject提供的一个方法

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

这个方法需要被观察的对象调用,用来为自己添加其他观察者

方法参数

  • observer:添加的观察者对象,意思让该对象观察自己。
  • keyPath:观察属性名,例如想观察name属性,那输入@"name"即可
  • options:观察值的类型,分别可选初始值,新值和旧值。
  • context:回调上下文,因一个观察者可以观察多个对象,但回调方法都是这一个方法,所有可以通过这个参数类分辨是那个观察操作的回调。

当被观察对象的属性发生变化时,将会回调一个固定的方法,且此方法不需要被注册,默认生效

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

通过此回调方法,可以反馈到观察者如下信息

  • keyPath:被观察对象属性
  • object:被观察对象
  • change:改变内容
  • context:注册观察者时输入的上下文信息

下面通过一个完整的案例来展现一下键值观察的模式

@interface Student : NSObject

@property(strong, nonatomic) NSString * name;

@end
@interface Teacher : NSObject

@property(strong, nonatomic) Student * stu;

@end

@implementation Teacher

-(void)test
{
    self.stu = [[Student alloc] init];
    [self.stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];

    self.stu.name = @"test";
}


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@",change);
}

-(void)dealloc
{
    [self.stu removeObserver:self forKeyPath:@"name"];
}


@end
main()
{
    Teacher * tea = [[Teacher alloc] init];
    [tea test];
}

运行上述代码,即可看到输出结果,当stu对象的name属性发生改变是,键值观察回调方法变会被调用,同时输出change中的信息。

同时需要注意的是,在dealloc方法中移动要移除观察者,否则在对象是否之后,再产生的键值观察回调将会发送给一个野指针,产生概率性崩溃信息。

3,消息模式

消息模式是OC中较为特殊的一种开发模式,它为两个不能相见但有需要互通消息的对象提供了一个传递信息的机制。

通常我们在使用回调或者键值观察时,都需要直接获取要产生回调事件的组件对象或需要观察的对象。

但在一些特殊情况,例如之后的App开发课程中需要对键盘对象进行监控,但缺无法获取键盘对象,因键盘对象只在用户触发响应事件是才被创建。这样我们便可以采用消息的方式,接收键盘对象发出来的消息,从而实现对键盘对象行为的监控。

使用消息开发模式需要掌握一下三个步骤

  • 获取消息中心
  • 订阅消息
  • 取消订阅
  • 发送消息

获取消息中心:

NSNotificationCenter * center = [NSNotificationCenter defaultCenter];

消息中心对象需要通过单例模式获取,不能进行alloc操作,因为全局必须保证只有一个消息中心,才能够将消息正确的传递。

订阅消息:

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

该方法为消息中心对象的方法,其参数分别为

  • observer:接收消息回调的对象,类似目标动作回调中的target对象。
  • aSelector:消息到达时回调的方法,与目标动作回调中的action功能一致。
  • aName:订阅消息的名称,相当于筛选器,只接收指定名称的消息,如果为nil,则接收所有消息。
  • anObject:发送消息的对象

取消订阅:

- (void)removeObserver:(id)observer;

在dealloc方法中需要消息中心对象调用此方法取消订阅

发送消息分为两步,第一步是创建消息,第二步是发送消息

NSNotification * noti = [NSNotification notificationWithName:@"test" object:self userInfo:@{@"key":@"value"}];

创建一条消息需要三个参数

  • 消息名
  • 发送消息对象,通常填self
  • 消息携带的信息,为一个字典,其中键值对可自定义。
NSNotificationCenter * center = [NSNotificationCenter defaultCenter];

NSNotification * noti = [NSNotification notificationWithName:@"test" object:self userInfo:@{@"key":@"value"}];

[center postNotification:noti];

发送消息是消息中心的功能,调用相应的发送方法,即可把一个消息发送出去,如果在此之前,有对象订阅了相同名称的消息,那么该对象的消息回调方法会被调用。

OC教程9-开发模式

标签:oc开发模式   单例模式   oc观察者模式   oc消息模式   

原文地址:http://blog.csdn.net/yangbingbinga/article/details/46314961

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!