NSNotificationCenter同步异步的问题

来源:互联网 发布:centos怎么读 编辑:程序博客网 时间:2024/06/05 23:07
<div id="article_content" class="article_content">
        <div class="markdown_views"><p>iOS 提供了一种 “同步的” 消息通知机制NSNotificationCenter,观察者只要向消息中心注册, 即可接受其他对象发送来的消息,消息发送者和消息接受者两者可以互相一无所知,完全解耦。</p>


<p><strong>基于这点,我们可以用来两个对象之间的通信!</strong></p>


<p>注意,每个运行中的application都有一个NSNotificationCenter的单例,如源代码:</p>


<pre class="prettyprint" name="code"><code class="hljs diff has-numbering"><span class="hljs-addition">+ (NSNotificationCenter *)defaultCenter;</span></code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>只要任何一个对象注册消息通知,如果该消息被发送,那么该对象将能够收到消息通知;从而实现在这个对象去执行另外一个对象的函数;</p>






<h3 id="使用方法"><a name="t0"></a>使用方法:</h3>






<h4 id="1-观察者注册消息通知"><a name="t1"></a>1. 观察者注册消息通知</h4>






<pre class="prettyprint" name="code"><code class="hljs erlang has-numbering"><span class="hljs-pp">- <span class="hljs-params">(void)</span>addObserver:<span class="hljs-params">(id)</span>notificationObserver
           selector:<span class="hljs-params">(<span class="hljs-variable">SEL</span>)</span>notificationSelector
               name:<span class="hljs-params">(<span class="hljs-variable">NSString</span> *)</span>notificationName
             object:<span class="hljs-params">(id)</span>notificationSender</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul></pre>


<p>addObserver(观察者) :  self <br>
selector(收到消息后要执行的函数):  notificationSelector  <br>
name (消息通知的名字):     notificationName <br>
object (消息发送者) : 表示接收哪个发送者的通知,如果第四个参数为nil,接收所有发送者的通知</p>


<p>使用实例:</p>






<pre class="prettyprint" name="code"><code class="hljs css has-numbering"><span class="hljs-attr_selector">[[NSNotificationCenter defaultCenter]</span> <span class="hljs-tag">addObserver</span><span class="hljs-pseudo">:self</span> <span class="hljs-tag">selector</span>:<span class="hljs-at_rule">@<span class="hljs-keyword">selector(handleNotification:)</span> name:TEST_NOTIFICATION object:nil]</span>;</code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>注意的问题: <br>
(1)Observer不能为nil; <br>
(2 )如果name设置为nil,则表示接收所有消息; <br>
(3)监听同一条通知的多个观察者,在通知到达时,它们执行回调的顺序是不确定的,所以我们不能去假设操作的执行会按照添加观察者的顺序来执行</p>


<h4 id="2-发送消息通知与观察者注册消息通知对应"><a name="t2"></a>2. 发送消息通知(<strong>与观察者注册消息通知对应</strong>)</h4>






<pre class="prettyprint" name="code"><code class="hljs css has-numbering"><span class="hljs-tag">-</span> <span class="hljs-tag">postNotification</span>:
– <span class="hljs-tag">postNotificationName</span><span class="hljs-pseudo">:object</span>:
– <span class="hljs-tag">postNotificationName</span><span class="hljs-pseudo">:object</span><span class="hljs-pseudo">:userInfo</span>:</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>


<p>我们可以根据需要指定通知的发送者(object)并附带一些与通知相关的信息(userInfo),当然这些发送者和userInfo(注意,这里userInfo是个字典)可以封装在一个NSNotification对象中,由- postNotification:来发送。注意,- postNotification:的参数不能为空,否则会引发一个异常</p>


<p>使用实例:</p>


<pre class="prettyprint" name="code"><code class="hljs css has-numbering"><span class="hljs-attr_selector">[[NSNotificationCenter defaultCenter]</span> <span class="hljs-tag">postNotificationName</span><span class="hljs-pseudo">:TEST_NOTIFICATION</span> <span class="hljs-tag">object</span><span class="hljs-pseudo">:nil</span>];</code><ul class="pre-numbering"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>


<p>这样,就能够实现在两个类(或者一个类内回调)之间的消息通信,可以理解成实现了回调函数;</p>






<h4 id="3移除观察者与观察者注册消息通知相对应"><a name="t3"></a>3.移除观察者(与观察者注册消息通知相对应)</h4>






<pre class="prettyprint" name="code"><code class="hljs erlang has-numbering"><span class="hljs-pp">- <span class="hljs-params">(void)</span>removeObserver:<span class="hljs-params">(id)</span>notificationObserver


- <span class="hljs-params">(void)</span>removeObserver:<span class="hljs-params">(id)</span>notificationObserver name:<span class="hljs-params">(<span class="hljs-variable">NSString</span> *)</span>notificationName object:<span class="hljs-params">(id)</span>notificationSender</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets_01.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>


<p>引用博文<a href="http://southpeak.github.io/blog/2015/03/20/nsnotificationcenter/">NSNotificationCenter</a>内容:</p>


<p>(1)由于注册观察者时(不管是哪个方法),通知中心会维护一个观察者的弱引用,所以在释放对象时,要确保移除对象所有监听的通知。否则,可能会导致程序崩溃或一些莫名其妙的问题。</p>


<p>(2)对于第二个方法,如果notificationName为nil,则会移除所有匹配notificationObserver和notificationSender的通知,同理notificationSender也是一样的。而如果notificationName和notificationSender都为nil,则其效果就与第一个方法是一样的了。大家可以试一下。</p>


<p>(3)最有趣的应该是这两个方法的使用时机。–removeObserver:适合于在类的dealloc方法中调用,这样可以确保将对象从通知中心中清除;而在viewWillDisappear:这样的方法中,则适合于使用-removeObserver:name:object:方法,以避免不知情的情况下移除了不应该移除的通知观察者。例如,假设我们的ViewController继承自一个类库的某个ViewController类(假设为SKViewController吧),可能SKViewController自身也监听了某些通知以执行特定的操作,但我们使用时并不知道。如果直接在viewWillDisappear:中调用–removeObserver:,则也会把父类监听的通知也给移除。</p>


<p>(4)关于注册监听者,还有一个需要注意的问题是,每次调用addObserver时,都会在通知中心重新注册一次,即使是同一对象监听同一个消息,而不是去覆盖原来的监听。这样,当通知中心转发某一消息时,如果同一对象多次注册了这个通知的观察者,则会收到多个通知。</p>






<h4 id="4关于同步异步"><a name="t4"></a>4.关于同步异步</h4>


<p><strong>默认的NSNotificationCenter是同步的</strong>,这是一般人忽略的地方,可以参考这篇好文<a href="http://blog.csdn.net/junjun150013652/article/details/44343365"> NSNotificationCenter的同步和异步</a></p>


<p>本文参考了以下博文: <br>
<a href="http://southpeak.github.io/blog/2015/03/20/nsnotificationcenter/">NSNotificationCenter</a> <br>
<a href="http://www.cnblogs.com/xunziji/p/3257447.html">IOS 消息机制(NSNotificationCenter)</a></p></div>
        <script type="text/javascript">
            $(function () {
                $('pre.prettyprint code').each(function () {
                    var lines = $(this).text().split('\n').length;
                    var $numbering = $('<ul></ul>').addClass('pre-numbering').hide();
                    $(this).addClass('has-numbering').parent().append($numbering);
                    for (i = 1; i <= lines; i++) {
                        $numbering.append($('<li></li>').text(i));
                    };
                    $numbering.fadeIn(1700);
                });
            });
        </script>
   
</div>
0 0
原创粉丝点击