我添加了多个观察者奥鲁莫掉落,在dealloc里移除掉,移除一次就行么

我添加了多个观察者,在dealloc里移除掉,移除一次就行么_百度知道
我添加了多个观察者,在dealloc里移除掉,移除一次就行么
提问者采纳
:什么是观察者模式?我们先打个比方,这就像你订报纸。比如你想知道美国最近放生了些新闻,你可能会订阅一份美国周刊,然后一旦美国有了新的故事,美国周刊就发一刊,并邮寄给你,当你收到这份报刊,然后你就能够了解美国最新的动态。其实这就
来自团队:
其他类似问题
为您推荐:
观察者的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁IOS 监听(NSNotification)的优缺点和项目实践应用 - CSDN博客
在IOS应用开发中有一个”Notification Center“的概念。它是一个单例对象,允许当事件发生时通知一些对象。它允许我们在低程度耦合的情况下,满足控制器与一个任意的对象进行通信的目的。这种模式的基本特征是为了让其他的对象能够接收到在该controller中发生某种事件而产生的消息,controller用一个key(通知名称)。这样对于controller来说是匿名的,其他的使用同样的key来注册了该通知的对象(即观察者)能够对通知的事件作出反应。
&&&&&&&优势:
&&&&& & 1.不需要编写多少代码,实现比较简单;
&&&&&&& 2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
&&&&&&& 3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息
&&&&&&&缺点:
&&&&&&& 1.在编译期不会检查通知是否能够被观察者正确的处理;&
&&&&&&& 2.在释放注册的对象时,需要在通知中心取消注册;
&&&&&&& 3.在调试的时候应用的工作以及控制过程难跟踪;
&&&&&&& 4.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;
&&&&&&& 5.controller和观察者需要提前知道通知名称、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况;
&&&&&&& 6.通知发出后,controller不能从观察者获得任何的反馈信息。
1、.注册通知:addObserver:selector:name:object,并实现触发通知后要实现的操作
& &[[NSNotificationCenterdefaultCenter]
addObserver:selfselector:@selector(reloadJpushData:)name:@&JPUSHNOTIFICATION&object:nil];
- (void)reloadJpushData: (NSNotification *)sender{&
[self getData];
2、发送通知:postNotificationName:object(就在触发通知的方法里写)
[[NSNotificationCenterdefaultCenter]
postNotificationName:@&JPUSHNOTIFICATION&object:nil];
3、移除通知:removeObserver:和removeObserver:name:object:
其中,removeObserver:是删除通知中心保存的调度表一个观察者的所有入口,而removeObserver:name:object:是删除匹配了通知中心保存的调度表中观察者的一个入口。我以前发现不移除通知也不会报错,但是想想不用的东西进行移除,然后用的时候到再进行注册,这是一种良好的编程方式,有始有终,不要给程序留下潜在的问题。在dealloc方法下实现
这个比较简单,直接调用该方法就行。例如:
移除单个通知:[[NSNotificationCenter defaultCenter] removeObserver:self name:@&JPUSHNOTIFICATION& object:self];
移除当前所有通知:[[NSNotificationCenterdefaultCenter]
removeObserver:self];KVC: &key values coding & 键值编码,间接通过字符串对应的key取出、修改其对应的属性。
可以访问和修改私有成员变量、readOnly成员变量的值。(替换系统自带的导航栏、替换系统自带的Tabbar等)
示例代码:
@interface ZYPerson : NSObject
@property (nonatomic,
copy, readonly)
NSString *
- (instancetype)initWithName:(NSString *)
#import &ZYPerson.h&
@implementation ZYPerson
- (instancetype)initWithName:(NSString *)name
&&&&if (self = [super init]) {
&&&&&&&&_name =
&&&&return
#import &ViewController.h&
#import &ZYPerson.h&
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
&&&&[super viewDidLoad];
&&&&// Do any additional setup after loading the view, typically from a nib.
&&&&ZYPerson *personOne = [[ZYPerson alloc] initWithName:@&张三&];
&&&&NSLog(@&%@&,personOne.name);
然后,我发现名字写错了,需要修改
//&&& personOne.name = @&王五&;&&&&&& //&
如果这么写,发现编译器报错,报错很正常,我写的是readOnly
那么,在不改变原来代码的结构上,如何修改?在这里,KVO就有用处了
&&&&[personOne setValue:@&王五& forKeyPath:@&name&];
&&&&NSLog(@&%@&,personOne.name);
&这仅仅只是一个示例,KVC当然是强大的,UIKit框架里面很多属性是readOnly、私有的,往往我们在开发中会觉得有一些属性不好用,想改变吧,要么是readOnly,要是是私有的,难道重新写一套?但是耗时耗力,项目需要赶进度的话,就得加班。这个时候,KVC的作用就大了,我们可以自定义那些特定需求的控件,然后用KVC将系统自带的换掉,换成自定义的,简单快速轻松就可以搞定了。当然,要是系统没有对应属性的控件,就只能自定义了。
KVO是用来做属性监听的,用完后必须要移除它。
其实现原理:KVO是基于runtime机制实现的,当某个类的对象第一次被观察时,系统就会在运行期动态的创建一个该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法,派生类在重写基类的setter方法中实现真正的通知机制。
如此,来看看代码里面KVO怎么实现监听一个对象值的改变:
#import &Foundation/Foundation.h&
@interface ZYPerson : NSObject
@property (nonatomic,
copy, readonly)
NSString *
@property (nonatomic, assign)
- (instancetype)initWithName:(NSString *)
#import &ZYPerson.h&
@implementation ZYPerson
- (instancetype)initWithName:(NSString *)name
&&&&if (self = [super init]) {
&&&&&&&&_name =
&&&&return
&viewController里面的代码:
#import &ViewController.h&
#import &ZYPerson.h&
@interface ViewController ()
@property (nonatomic, strong) ZYPerson *personO
@implementation ViewController
- (void)viewDidLoad {
&&&&[super viewDidLoad];
&&&&// Do any additional setup after loading the view, typically from a nib.
&&&&self.personOne = [[ZYPerson alloc] initWithName:@&张三&];
&&&&self.personOne.age = 10;
&&&&//& personOne添加一个监听器,监听age属性的变化,options&
是属性怎么样的变化
&&&&[self.personOne addObserver:self forKeyPath:@&age& options:NSKeyValueObservingOptionNew context:nil];
&&&&//当属性变化了,会调用observeValueForKeyPath方法
&&&&self.personOne.age = 20;
- (void)dealloc
&&&&//必须要移除监听器
&&&&[self.personOne removeObserver:self forKeyPath:@&age&];
当被监听属性发生改变的时候,会调用此方法
&*& @param keyPath
&*& @param object&
属性所属的对象
&*& @param change&
属性的修改情况
&*& @param context
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary&NSString *,id& *)change context:(void *)context
当你在controller中添加多个KVO时,所有的回调都是走这个方法,那就必须对触发回调函数的来源进行判断
&&&&if (object ==
self.personOne && [keyPath isEqualToString:@&age&]) {
&&&&&&&&[self doSomethingWhenContextDidChanged];
&&&&&&&&/**
&&&&&&&&&*&
我们假设当前类还有父类,并且父类也有自己绑定了一些其他KVO呢?我们看到,这个回调函数体中只有一个判断,如果这个if不成立,这次KVO事件的触发就会到此中断了。但事实上,若当前类无法捕捉到这个KVO,那很有可能是在他的superClass,或者super-superClass...中
&&&&&&&&&*/
&&&&&&&&[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
- (void)doSomethingWhenContextDidChanged
&&&&NSLog(@&doSomethingWhenContextDidChanged&);
&上述,就是一个KVO的完整实现,但事实上,还是有瑕疵的,潜在的问题有可能出现在dealloc中对KVO的注销上。KVO的一种缺陷(其实不能称为缺陷,应该称为特性)是,当对同一个keypath进行两次removeObserver时会导致程序crash,这种情况常常出现在父类有一个kvo,父类在dealloc中remove了一次,子类又remove了一次的情况下。
三. NSNotification
一个类的属性发生改变,我们也可以使用NSNotification告诉其他对象,被改变的具体情况。
先上代码:
#import &Foundation/Foundation.h&
extern NSString *
const ZYAgeDidChangeN
@interface ZYPerson : NSObject
@property (nonatomic,
copy, readonly)
NSString *
@property (nonatomic, assign)
- (instancetype)initWithName:(NSString *)
#import &ZYPerson.h&
NSString * const ZYAgeDidChangeNotification = @&ZYAgeDidChangeNotification&;
@implementation ZYPerson
- (instancetype)initWithName:(NSString *)name
&&&&if (self = [super init]) {
&&&&&&&&_name =
&&&&return
//重写age的setter方法,在这里发送age被更改的notification
- (void)setAge:(int)age
&&&&_age =
&&&&[[NSNotificationCenter defaultCenter] postNotificationName:ZYAgeDidChangeNotification object:nil userInfo:nil];
&viewController里面的代码:
#import &ViewController.h&
#import &ZYPerson.h&
@interface ViewController ()
@property (nonatomic, strong) ZYPerson *personO
@implementation ViewController
- (void)viewDidLoad {
&&&&[super viewDidLoad];
&&&&// Do any additional setup after loading the view, typically from a nib.
&&&&[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomethingWhenContextDidChanged) name:ZYAgeDidChangeNotification object:nil];
&&&&self.personOne = [[ZYPerson alloc] initWithName:@&张三&];
&&&&self.personOne.age = 10;
&&&&//当属性变化了,会调用observeValueForKeyPath方法
&&&&self.personOne.age = 20;
- (void)dealloc
&&&&[[NSNotificationCenter defaultCenter] removeObserver:self];
- (void)doSomethingWhenContextDidChanged
&&&&NSLog(@&doSomethingWhenContextDidChanged&);
&这样,也是可以监听到对象属性的改变的,甚至,我们在用delegate来监控一些状态的改变也是可以做到的,这些都可以说是OC中的监听者模式。
只是说,需要注意,如果是跨控制器之间的监听、或者传递信息,建议用NSNotification更好,如果是view与它的ViewController之间的监听,用委托(也就是delegate)更好。
4. 观察者模式
KVO、NSNotification、委托都可以说是OC里面的监听者模式,NSNotification更重量级一些,除了监听外,还需负责传递信息等。
什么时候使用观察者模式:
有两种抽象类型相互依赖,将他们封装在各自的对象中,就可以对它们单独进行改变和复用。
对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
一个对象必须通知其他对象,而它又不知道其他对象是什么。
MVC是由各种复杂的设计模式组合而成的复合结构,观察者是其中的设计模式之一。视图与控制器联系在一起,等待会影响应用程序表现的事件发生。例如,当用户单击视图上的排序按钮时,事件会传递给控制器,模型在后台排序完毕后,会通知所有相关的控制器,让它们用新的数据更新视图。
在MVC中使用观察者模式,每个组件都能够被独立复用与扩展,而对关系中的其他组件没有太多干扰。所得到的高度可复用性与可扩展性,是把其全部逻辑放入一个类中所无法得到的。因此,向控制器添加额外的视图时,不用修改已有的设计和代码。同样,不同的控制器可以使用同一个模型,而不用对使用它们的其他控制器做修改。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:14次
排名:千里之外NSNotificationCenter - 推酷
NSNotificationCenter
一个NSNotificationCenter对象(通知中心)提供了在程序中广播消息的机制,它实质上就是一个通知分发表。这个分发表负责维护为各个通知注册的观察者,并在通知到达时,去查找相应的观察者,将通知转发给他们进行处理。
本文主要了整理了一下NSNotificationCenter的使用及需要注意的一些问题,并提出了一些未解决的问题,希望能在此得到解答。
获取通知中心
每个程序都会有一个默认的通知中心。为此,NSNotificationCenter提供了一个类方法来获取这个通知中心:
+ (NSNotificationCenter *)defaultCenter
获取了这个默认的通知中心对象后,我们就可以使用它来处理通知相关的操作了,包括注册观察者,移除观察者、发送通知等。
通常如果不是出于必要,我们一般都使用这个默认的通知中心,而不自己创建维护一个通知中心。
添加观察者
如果想让对象监听某个通知,则需要在通知中心中将这个对象注册为通知的观察者。早先,NSNotificationCenter提供了以下方法来添加观察者:
- (void)addObserver:(id)notificationObserver
selector:(SEL)notificationSelector
name:(NSString *)notificationName
object:(id)notificationSender
这个方法带有4个参数,分别指定了通知的观察者、处理通知的回调、通知名及通知的发送对象。这里需要注意几个问题:
notificationObserver不能为nil。
notificationSelector回调方法有且只有一个参数(NSNotification对象)。
如果notificationName为nil,则会接收所有的通知(如果notificationSender不为空,则接收所有来自于notificationSender的所有通知)。如代码清单1所示。
如果notificationSender为nil,则会接收所有notificationName定义的通知;否则,接收由notificationSender发送的通知。
监听同一条通知的多个观察者,在通知到达时,它们执行回调的顺序是不确定的,所以我们不能去假设操作的执行会按照添加观察者的顺序来执行。
对于以上几点,我们来重点关注一下第3条。以下代码演示了当我们的notificationName设置为nil时,通知的监听情况。
代码清单1:添加一个Observer,其中notificationName为nil
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];
- (void)handleNotification:(NSNotification *)notification
NSLog(@&notification = %@&, notification.name);
运行后的输出结果如下:
notification = TestNotification
notification = UIWindowDidBecomeVisibleNotification
notification = UIWindowDidBecomeKeyNotification
notification = UIApplicationDidFinishLaunchingNotification
notification = _UIWindowContentWillRotateNotification
notification = _UIApplicationWillAddDeactivationReasonNotification
notification = _UIApplicationDidRemoveDeactivationReasonNotification
notification = UIDeviceOrientationDidChangeNotification
notification = _UIApplicationDidRemoveDeactivationReasonNotification
notification = UIApplicationDidBecomeActiveNotification
可以看出,我们的对象基本上监听了测试程序启动后的所示消息。当然,我们很少会去这么做。
而对于第4条,使用得比较多的场景是监听UITextField的修改事件,通常我们在一个ViewController中,只希望去监听当前视图中的UITextField修改事件,而不希望监听所有UITextField的修改事件,这时我们就可以将当前页面的UITextField对象指定为notificationSender。
在iOS 4.0之后,NSNotificationCenter为了跟上时代,又提供了一个以block方式实现的添加观察者的方法,如下所示:
- (id&NSObject&)addObserverForName:(NSString *)name
object:(id)obj
queue:(NSOperationQueue *)queue
usingBlock:(void (^)(NSNotification *note))block
大家第一次看到这个方法时是否会有这样的疑问:观察者呢?参数中并没有指定具体的观察者,那谁是观察者呢?实际上,与前一个方法不同的是,前者使用一个现存的对象作为观察者,而这个方法会创建一个匿名的对象作为观察者(即方法返回的id&NSObject&对象),这个匿名对象会在指定的队列(queue)上去执行我们的block。
这个方法的优点在于添加观察者的操作与回调处理操作的代码更加紧凑,不需要拼命滚动鼠标就能直接找到处理代码,简单直观。这个方法也有几个地方需要注意:
name和obj为nil时的情形与前面一个方法是相同的。
如果queue为nil,则消息是默认在post线程中同步处理,即通知的post与转发是在同一线程中;但如果我们指定了操作队列,情况就变得有点意思了,我们一会再讲。
block块会被通知中心拷贝一份(执行copy操作),以在堆中维护一个block对象,直到观察者被从通知中心中移除。所以,应该特别注意在block中使用外部对象,避免出现对象的循环引用,这个我们在下面将举例说明。
如果一个给定的通知触发了多个观察者的block操作,则这些操作会在各自的Operation Queue中被并发执行。所以我们不能去假设操作的执行会按照添加观察者的顺序来执行。
该方法会返回一个表示观察者的对象,记得在不用时释放这个对象。
下面我们重点说明一下第2点和第3点。
关于第2点,当我们指定一个Operation Queue时,不管通知是在哪个线程中post的,都会在Operation Queue所属的线程中进行转发,如代码清单2所示:
代码清单2:在指定队列中接收通知
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserverForName:TEST_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(@&receive thread = %@&, [NSThread currentThread]);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@&post thread = %@&, [NSThread currentThread]);
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];
在这里,我们在主线程里添加了一个观察者,并指定在主线程队列中去接收处理这个通知。然后我们在一个全局队列中post了一个通知。我们来看下输出结果:
post thread = &NSThread: 0x7ffe&{number = 2, name = (null)}
receive thread = &NSThread: 0x7ffe03508b30&{number = 1, name = main}
可以看到,消息的post与接收处理并不是在同一个线程中。如上面所提到的,如果queue为nil,则消息是默认在post线程中同步处理,大家可以试一下。
对于第3点,由于使用的是block,所以需要注意的就是避免引起循环引用的问题,如代码清单3所示:
代码清单3:block引发的循环引用问题
@interface Observer : NSObject
@property (nonatomic, assign) NSI
@property (nonatomic, weak) id&NSObject&
@implementation Observer
- (instancetype)init
self = [super init];
NSLog(@&Init Observer&);
// 添加观察者
_observer =
[[NSNotificationCenter defaultCenter] addObserverForName:TEST_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(@&handle notification&);
// 使用self
self.i = 10;
#pragma mark - ViewController
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createObserver];
// 发送消息
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];
- (void)createObserver {
Observer *observer = [[Observer alloc] init];
运行后的输出如下:
Init Observer
handle notification
我们可以看到createObserver中创建的observer并没有被释放。所以,使用 – addObserverForName:object:queue:usingBlock:一定要注意这个问题。
移除观察者
与注册观察者相对应的,NSNotificationCenter为我们提供了两个移除观察者的方法。它们的定义如下:
- (void)removeObserver:(id)notificationObserver
- (void)removeObserver:(id)notificationObserver name:(NSString *)notificationName object:(id)notificationSender
前一个方法会将notificationObserver从通知中心中移除,这样notificationObserver就无法再监听任何消息。而后一个会根据三个参数来移除相应的观察者。
这两个方法也有几点需要注意:
由于注册观察者时(不管是哪个方法),通知中心会维护一个观察者的弱引用,所以在释放对象时,要确保移除对象所有监听的通知。否则,可能会导致程序崩溃或一些莫名其妙的问题。
对于第二个方法,如果notificationName为nil,则会移除所有匹配notificationObserver和notificationSender的通知,同理notificationSender也是一样的。而如果notificationName和notificationSender都为nil,则其效果就与第一个方法是一样的了。大家可以试一下。
最有趣的应该是这两个方法的使用时机。–removeObserver:适合于在类的dealloc方法中调用,这样可以确保将对象从通知中心中清除;而在viewWillDisappear:这样的方法中,则适合于使用-removeObserver:name:object:方法,以避免不知情的情况下移除了不应该移除的通知观察者。例如,假设我们的ViewController继承自一个类库的某个ViewController类(假设为SKViewController吧),可能SKViewController自身也监听了某些通知以执行特定的操作,但我们使用时并不知道。如果直接在viewWillDisappear:中调用–removeObserver:,则也会把父类监听的通知也给移除。
关于注册监听者,还有一个需要注意的问题是,每次调用addObserver时,都会在通知中心重新注册一次,即使是同一对象监听同一个消息,而不是去覆盖原来的监听。这样,当通知中心转发某一消息时,如果同一对象多次注册了这个通知的观察者,则会收到多个通知,如代码清单4所示:
代码清单4:同一对象多次注册同一消息
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];
- (void)handleNotification:(NSNotification *)notification
NSLog(@&notification = %@&, notification.name);
其输出结果如下所示:
notification = TestNotification
notification = TestNotification
可以看到对象处理了两次通知。所以,如果我们需要在viewWillAppear监听一个通知时,一定要记得在对应的viewWillDisappear里面将观察者移除,否则就可能会出现上面的情况。
最后,再特别重点强调的非常重要的一点是,在释放对象前,一定要记住如果它监听了通知,一定要将它从通知中心移除。如果是用 – addObserverForName:object:queue:usingBlock:,也记得一定得移除这个匿名观察者。说白了就一句话,添加和移除要配对出现。
注册了通知观察者,我们便可以随时随地的去post一个通知了(当然,如果闲着没事,也可以不注册观察者,post通知随便玩,只是没人理睬罢了)。NSNotificationCenter提供了三个方法来post一个通知,如下所示:
- postNotification:
– postNotificationName:object:
– postNotificationName:object:userInfo:
我们可以根据需要指定通知的发送者(object)并附带一些与通知相关的信息(userInfo),当然这些发送者和userInfo可以封装在一个NSNotification对象中,由- postNotification:来发送。注意,- postNotification:的参数不能为空,否则会引发一个异常,如下所示:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSNotificationCenter postNotification:]: notification is nil'
每次post一个通知时,通知中心都会去遍历一下它的分发表,然后将通知转发给相应的观察者。
另外,通知的发送与处理是同步的,在某个地方post一个消息时,会等到所有观察者对象执行完处理操作后,才回到post的地方,继续执行后面的代码。如代码清单5所示:
代码清单5:通知的同步处理
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:TEST_NOTIFICATION object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:TEST_NOTIFICATION object:nil];
NSLog(@&continue&);
- (void)handleNotification:(NSNotification *)notification
NSLog(@&handle notification&);
运行后输出结果是:
handle notification
翻了好些资料,还有两个问题始终没有明确的答案。
首先就是通知中心是如何维护观察者对象的。可以明确的是,添加观察者时,通知中心没有对观察者做retain操作,即不会使观察者的引用计数加1。那通知中心维护的是观察者的weak引用呢还是unsafe_unretained引用呢?
个人认为可能是unsafe_unretained的引用,因为我们知道如果是weak引用,其所指的对象被释放后,这个引用会被置成nil。而实际情况是通知中心还会给这个对象发送消息,并引发一个异常。而如果向nil发送一个消息是不会导致异常的。
另外,我们知道NSNotificationCenter实现的是观察者模式,而且通常情况下消息在哪个线程被post,就在哪个线程被转发。而从上面的描述可以发现, -addObserverForName:object:queue:usingBlock:添加的匿名观察者可以在指定的队列中处理通知,那它的实现机制是什么呢?
在我们的应用程序中,一个大的话题就是两个对象之间如何通信。我们需要根据对象之间的关系来确定采用哪一种通信方式。对象之间的通信方式主要有以下几种:
直接方法调用
Target-Action
回调(block)
一般情况下,我们可以根据以下两点来确定使用哪种方式:
通信对象是一对一的还是一对多的
对象之间的耦合度,是强耦合还是松耦合
Objective-C中的通知由于其广播性及松耦合性,非常适合于大的范围内对象之间的通信(模块与模块,或一些框架层级)。通知使用起来非常方便,也正因为如此,所以容易导致滥用。所以在使用前还是需要多想想,是否有更好的方法来实现我们所需要的对象间通信。毕竟,通知机制会在一定程度上会影响到程序的性能。
对于使用NSNotificationCenter,最后总结一些小建议:
在需要的地方使用通知。
注册的观察者在不使用时一定要记得移除,即添加和移除要配对出现。
尽可能迟地去注册一个观察者,并尽可能早将其移除,这样可以改善程序的性能。因为,每post一个通知,都会是遍历通知中心的分发表,确保通知发给每一个观察者。
记住通知的发送和处理是在同一个线程中。
使用-addObserverForName:object:queue:usingBlock:务必处理好内存问题,避免出现循环引用。
NSNotificationCenter是线程安全的,但并不意味着在多线程环境中不需要关注线程安全问题。不恰当的使用仍然会引发线程问题。
最后,“@叶孤城___”叶大大在微博中推荐了几篇文章,即参考中的4-7,值得细读一下。
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见

我要回帖

更多关于 观察者奥尔加隆掉落 的文章

 

随机推荐