<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_MR_H's Blog</title><subtitle type="text">Interest in technology,focus on the application.Linux And Network On The Way.</subtitle><id>http://feed.cnblogs.com/blog/u/68903/rss</id><updated>2012-03-16T15:23:22Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/68903/rss"/><entry><id>http://www.cnblogs.com/huangwei/archive/2012/03/16/2402322.html</id><title type="text">cocos2d基础介绍</title><summary type="text">这篇文章主要会介绍一些cocos2d的基础类，以及他们的用途。 cocos2d中，大量使用了单例（singleton）模式，单例其实就是一个普通的类，但是它在整个应用程序生命周期内只实例化一次，cocos2d中，要访问单例对象，基本上都是使用shared开头的方法(目前为止，我没有发现过有不这样使用的单例)。如果你还没看懂单例是什么，那么看看下面这个例子你就知道了。static MyManager *shareManager = nil;+(MyManager) sharedManager{ if(shareManager == nil) { share...</summary><published>2012-03-16T15:13:00Z</published><updated>2012-03-16T15:13:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2402322.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2402322.html"/><content type="html">&lt;p class="p1"&gt;这篇文章主要会介绍一些cocos2d的基础类，以及他们的用途。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;cocos2d中，大量使用了单例（singleton）模式，单例其实就是一个普通的类，但是它在整个应用程序生命周期内只实例化一次，cocos2d中，要访问单例对象，基本上都是使用shared开头的方法(目前为止，我没有发现过有不这样使用的单例)。如果你还没看懂单例是什么，那么看看下面这个例子你就知道了。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; MyManager *shareManager = nil;&lt;br /&gt;&lt;br /&gt;+(MyManager) sharedManager&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(shareManager == nil)&lt;br /&gt;&lt;br /&gt;     {&lt;br /&gt;&lt;br /&gt;          shareManager = [[MyManager alloc] init];&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; shareManager;&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;p class="p1"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p1"&gt;我觉得单例应该是包含了一些公用的方法，而且调用这些方法，不会去修改单例的属性，否则其他的类来调用单例的时候，所遇到的结果就是未知的了。说完单例，我们先来说说一个重要的单例类&amp;mdash;&amp;mdash;CCDirector。CCDiretor类是Cococs2d游戏引擎的核心，它存储了cocos2d种大量的全局配置信息，而且管理着所有的cocos2d场景。Dirctor的主要作用有一下几点：&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;切换场景&lt;/li&gt;&lt;li class="li1"&gt;存储cocos2d的配置信息&lt;/li&gt;&lt;li class="li1"&gt;访问试图（包含OpenGL、UIView、UIWindow）&lt;/li&gt;&lt;li class="li1"&gt;暂停、恢复以及终止游戏&lt;/li&gt;&lt;li class="li1"&gt;在UIKit和OpenGL之间转换坐标&lt;/li&gt;&lt;/ul&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;&lt;strong&gt;CCNode类&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;接下来，说说CCNode类。cocos2d中，所有的节点都继承自CNode类，它是一个没有具体显示的抽象类，仅用于定义所有的公共属性和方法。首先我们来看一下cocos文档里面列举出来的类的继承关系，可以从中发现CCScene、CCSprite都继承自CCNode，以前CCLayer也应该是继承自CCNode，但是在1.0.1的文档中查不到这个类，先记录下，等下再去查。&lt;/p&gt;&lt;p class="p3"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/121543/2012031623062398.png" alt="" width="800" /&gt;&lt;/p&gt;&lt;p class="p1"&gt;再来看看这个类的部分公共函数，里面包含了各种对节点的操作，增加、删除、获取节点、调度（即隔多少秒执行一次，稍后会详细说、取消调度、开始播放动作、停止动作等）：&lt;/p&gt;&lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;addChild:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;addChild:z:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;addChild:z:tag:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;removeFromParentAndCleanup:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;removeChild:cleanup:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;removeChildByTag:cleanup:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;removeAllChildrenWithCleanup:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p6"&gt;&lt;span class="s1"&gt;(&lt;/span&gt;&lt;strong&gt;CCNode&lt;/strong&gt;&lt;span class="s1"&gt;&amp;nbsp;*)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;getChildByTag:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;reorderChild:z:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;cleanup&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;draw&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;visit&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;transform&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;transformAncestors&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(CGRect)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;boundingBox&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(CGRect)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;boundingBoxInPixels&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p6"&gt;&lt;span class="s1"&gt;(&lt;/span&gt;&lt;strong&gt;CCAction&lt;/strong&gt;&lt;span class="s1"&gt;&amp;nbsp;*)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;runAction:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;stopAllActions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;stopAction:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;stopActionByTag:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p6"&gt;&lt;span class="s1"&gt;(&lt;/span&gt;&lt;strong&gt;CCAction&lt;/strong&gt;&lt;span class="s1"&gt;&amp;nbsp;*)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;getActionByTag:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(NSUInteger)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;numberOfRunningActions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;scheduleUpdate&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;scheduleUpdateWithPriority:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;schedule:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;schedule:interval:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;unschedule:&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;unscheduleAllSelectors&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;resumeSchedulerAndActions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="td1" valign="top"&gt;&lt;p class="p4"&gt;(void)&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;td class="td2" valign="bottom"&gt;&lt;p class="p5"&gt;&lt;span class="s1"&gt;-&amp;nbsp;&lt;/span&gt;&lt;strong&gt;pauseSchedulerAndActions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;&lt;strong&gt;CCScene类&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;一个CCScene对象往往是场景图种的第一个节点。通常来说，CCScene节点的第一层子节点一定是CCLayer的子类，而CCScene对象本身，通常是利用CCLayer对象种的静态方法+(id)scene来创建，而且游戏中的各个对象，也通常是由这些子节点（CCLayer）来保存，而不是CCScene本身来保存，这样做的好处，会在CCLayer部分介绍。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1、场景类跟app建立关系上&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;我们可以把要显示的第一个场景，加在AppDelegate中applicationDidFinishLaunching方法的最后，类似如下：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;[[CCDirector sharedDirector] runWithScene:[HelloWorld scene]];&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HelloWold类是一个继承自CCLayer的类，scene是其中的一个静态方法，用来将layer加入scene里面，如下所示：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;     +(&lt;span style="color: #0000ff;"&gt;id&lt;/span&gt;)scene&lt;br /&gt;&lt;br /&gt;     {&lt;br /&gt;&lt;br /&gt;          CCScene *scene      = [CCScene node];&lt;br /&gt;&lt;br /&gt;          CCLayer *layer         = [HelloWord node];&lt;br /&gt;&lt;br /&gt;          [scene addChild:layer];&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;          &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; scene;&lt;br /&gt;&lt;br /&gt;     }&lt;/div&gt;&lt;p class="p1"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2、内存使用&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;当进行场景替换的时候，cocos2d会把自己占用的内存清理干净，它会删除所有的节点，停止所有的动作，并且对所有用选择器选中的方法取消调度。但是，由于在进行场景替换时，新场景往往在旧场景释放之前就被加载到内存了，这会导致内存负荷瞬间加大，这个问题在使用场景转换动画的时候，显得格外明显。这时候，场景首先会被创建，然后过渡效果运行，一直要到过度效果运行完毕之后，旧场景才会从内存中释放。&lt;/p&gt;&lt;p class="p1"&gt;由于场景替换的时候，会停止所有的动作，那么可否在播放场景过渡动画前先把前一个场景截屏，然后释放掉前一个场景再播放动画，这样的话，就能节省不少内存。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;3、场景的推进和弹出&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;cocos2d种有pushScene和popScene这两个有用的方法，这两个方法用来在不释放旧场景内存的情况下运行新场景，可以加快场景替换的速度。由于很多场景可以互相叠加的存在于内存之中，很容易就会忘记弹出一个场景，或者对于同一个场景弹出太多遍。学过堆栈的同学，应该知道这种情况的危险性。但是这个用来切换setting还是不错的选择，因为setting一般都不怎么占内存，当然，特殊情况除外。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;&lt;strong&gt;CCTransitonScene&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;场景过渡动画有时候能为游戏添色不少。在cocos2d中，要使用过度动画还是比较简单的，只要在场景转换时添加两行代码就行了。比如下面这个淡入淡出效果：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; CCFadeTransition *tran = [CCFadeTransition transitionWithDuration:&lt;span style="color: #800080;"&gt;1&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;                                                  scene:[HelloWorld scene] &lt;br /&gt;&lt;br /&gt;                                                  withColor:ccWHITE];&lt;br /&gt;&lt;br /&gt;[[CCDirector sharedDirector] replaceScene:tran];&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CCTransitonScene定义了很多的场景转换动画，看下下面这张类图应该能很清楚的知道：&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/121543/2012031623071379.png" alt="" width="800" /&gt;&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;&lt;strong&gt;CCLayer&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;开始在CCScene里面提到过，CCLayer本质是对节点进行分组，游戏中的各个对象，一般是用CCLayer来保存的。这样的好处是，可以很轻松的修改层的属性或者在该层上运行一个动作来影响层上的所有子节点。例如你可以对某一层施加一个动作，然后这个动作会对该层上的所有对象产生影响。当然，不使用层也能达到这样的效果，只要对每个对象分别进行操作即可，但是显然，不使用层的做法是非常低效的。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CCLayer能够接收触摸事件和加速剂事件，但是接收触摸或者加速计事件的开销是很大的，这也就导致有人说使用多个层会影响性能。实际上你可以使用任意多个蹭，与其他的节点相比，他们对于性能并没有太大的影响。如果太多的层需要接收和处理触摸或者加速计事件，可以只用一个蹭来接收和处理这些输入，然后在必要的情况下，通过这个层将输入事件通知给其他节点或者类。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1、接收触摸事件&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;使用self.isTouchEnabled = YES来显示启动接收触摸事件，一般会在init方法中开启此功能。下面列出几个常用单点触控的触摸事件：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;a）当手指接触到屏幕时被调用：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; -(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;/div&gt;&lt;p class="p8"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&lt;span class="s5"&gt;&amp;nbsp;　b)&lt;/span&gt;当手指离开屏幕时候被调用：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; -(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;c)当触摸时间被取消时调用：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;-(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;/div&gt;&lt;p class="p1"&gt;&lt;span class="s2"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;d)&lt;/span&gt;当手指在屏幕上移动的时候被调用：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; -(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;在使用单点触摸之前，要向层中添加以下方法来启用有针对性的触摸处理：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;     -(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;) registerWithTouchDispatcher&lt;br /&gt;&lt;br /&gt;     {&lt;br /&gt;&lt;br /&gt;          [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self&lt;br /&gt;                                                priority:INIT_MIN + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;                                                swallowsTouches:YES];&lt;br /&gt;&lt;br /&gt;     }&amp;nbsp;&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CCTouchBegan返回一个bool值，如果返回YES，就意味着不想让这个触摸被传送到其他优先级更低的有针对性的触摸处理，也就相当于你直接吞噬掉了这个触摸事件。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;由于触摸事件是由Cocoa Touch API接收的，因此一定要吧触摸位置转换成cocos2d所用的OpenGL坐标：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;-(CGPoint) locationFromTouch:(UITouch *)touch&lt;br /&gt;{&lt;br /&gt;      CGPoint touchLocation = [touch locationInView:[touch view]];&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; [[CCDirector sharedDirector] convertToGL:touchLocation];&lt;br /&gt;}&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2、接收加速计事件&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;同样，需要self.isAccelerometerEnabled = YES来显示启动加速计来接收加速计事件，但是这个事件的处理比触摸时间就简单多了，只需要向层里面添加一个特定方法来接收加速计事件：&lt;/p&gt;&lt;p class="p7"&gt;&lt;span class="s2"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;- (&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;)accelerometer:(UIAccelerometer*)accelerometer &lt;br /&gt;          didAccelerate:(UIAcceleration*)acceleration&lt;br /&gt;{&lt;br /&gt;     &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;可以利用以下参数来决定三维中任意方向的加速度&lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;acceleration.x   acceleration.y  acceleration.z&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt; }&lt;/div&gt;&lt;p class="p7"&gt;&lt;span class="s2"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;&lt;strong&gt;CCSprite&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="p3"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/121543/2012031623080551.png" alt="" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;CCSprite是cocos2d种最为常用的类，它用一副图像将精灵显示到屏幕上。要创建一个精灵很简单，比如你的工程的Resources分组下有一张叫做monster.png的图，那么只需要使用如下方法，就能将精灵显示在层上：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;CCSpirt *sprite = [[CCSprite spriteWithFile:&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;monster.png&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;]];&lt;br /&gt;&lt;br /&gt; [self addChild:sprite];&amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;通过上面的操作后，cocos2d内部会把该图片加载到CCTexture2D类的图像资源中。在这里，顺便提一下，由于ios设备只支持尺寸为&amp;ldquo;2的n次幂&amp;rdquo;的纹理，即图片的长宽只能伟：2、4、8等像素。如果你有一张贴图，大小为260*260像素32位色的图片，那么就比较悲剧了。你觉得它在内存中应该只占用260*260*4=270KB左右的空间，单实际上，它占用了512*512*4=1MB的内存。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CCSprite还有一个比较重要的就是位置问题，想象下现实生活中，如果你要把一张照片钉在墙上某个问题，你会怎么做？首先，你会把图钉插在照片上的某个点（在cocos2d中称为anchorPoint），然后你会确定要把这个图钉订在墙上的某个位置（在cocos2d种称为positon），这两个点就能确定照片在墙上的位置了。比如你想把照片放到左下角，那么你可以选择将图钉钉在照片的左下角（0，0），然后钉在墙的左下角（0，0）.或者，你可以选择把图钉定在照片的右上角（1，1），然后把照片订在墙的（照片长，照片宽）的位置。auchorPoint表示的其实是一个百分比，用来标明相对于图片左下角的（长＊百分比，宽＊百分比）像素的位置，比如auchorPoint为(0.5, 0.5), 那么在图片的坐标系里，它标明的位置就应该是（长＊0.5， 宽＊0.5）的位置，也就是图片的中心点。最好好anchorPoint设置成（0.5， 0.5），也就是在图片的中心，这样，当你进行旋转、缩放等动作的时候，会比较方便。幸运的是，anchorPoint的默认位置就是（0.5，0.5）.&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;CCLabelTTF&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/121543/2012031623084335.png" alt="" /&gt;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这个类的作用就是在屏幕上显示文本。cocos2d内部会以制定的字体作为参数创建一个CCTexture2D对象，也就是一张纹理，然后再用改纹理渲染出最后显示的文本.因为每次文本发生改变，就要做一次上述工作，所以cocos2d的文档中也建议改用CCLabelAtlas或者CCLabelBMFont代替。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;你可能会发现，每次修改标签上的文本时候，这些文本都会自动中对齐，如果要改成左对齐，或者右对齐这些，只需要改变anchorPoint的属性就可以了。&lt;/p&gt;&lt;ul class="ul1"&gt;&lt;li class="li1"&gt;动作&lt;/li&gt;&lt;/ul&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;动作是可以用来让节点执行诸如移动、旋转、缩放、变色、消失等很多动作。由于他们能作用在所有的节点上，因此可以对精灵、标签甚至菜单或整个场景施加动作。动作在完成后，会自动从节点上清除并释放它所占用的内存。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;动作又分为即时动作和延时动作。延时动作就是我们一般理解上的动作，比如让一个精灵移动到哪里。即时动作，一般就类似于设置精灵的属性等，及时动作平时看起来是没有多大意义的，一般要配合后文所述的动作序列。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1）重复动作&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这个很容易理解，就是让一个动作不停的重复，可以用这个方法创建无限循环的动画。使用起来也很简单，例如下面这个让一个节点不停的旋转：&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;CCRotateBy* rotateBy = [CCRotateBy actionWithDuration:&lt;span style="color: #800080;"&gt;2&lt;/span&gt;  angle:&lt;span style="color: #800080;"&gt;360&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;CCRepeatForever *repeat = [CCRepeatForever actionWithAction:rotateBy];&lt;br /&gt;&lt;br /&gt;[myNode runAction:repeat];&amp;nbsp;&lt;/div&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;还有一个类CCRepeat是让一个动画重复多少次，函数原型如下:&lt;span class="s7"&gt;&lt;strong&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;actionWithAction:(CCFiniteTimeAction *)action times:(NSUInteger) times;&lt;/div&gt;&lt;p class="p2"&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2、流畅动作（CCEaseAction）&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;一般的动作，比如你定义了一个物体是向哪个方向移动，那么它就会匀速的过去，但是很显然，我们喜欢更有点变化的动作，比如加速进入，然后迅速一段时间，再减速停止，流畅动作就是用来做这个的。&lt;/p&gt;&lt;p class="p2"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;3、动作序列&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; CCSequence，这个比较好理解，就是定义一组动作，然后让他们按照这个顺序执行。&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;上面介绍了cocos2d种一些重要的、常用的类，接下来的文章，会采用这些来做一个小demo，来温习一下这一篇文章的内容，不正确的地方，还请各位斧正。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2402322.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2402322.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2012/03/16/2399572.html</id><title type="text">cocos2d，开搞！</title><summary type="text">其实想写cocos2d的东西很久了，一直因为一些乱七八糟的事情，而没有写。前几天跟popple聊天的时候，popple说想要做一些这方面的东西，于是决定还是开始写这一系列的东西吧，记录自己学习，同时也分享给喜欢这个的朋友。 ios上开发游戏有很多方法，最原始的就是用原生的cocoa框架加上OpenGL ES开发，但是这种方法太复杂了，而且操作OpenGL也挺麻烦的，所以我选择了cocos 2d来作为框架开发。这个框架比较简单，而且资料也比较全，内置的box2d引擎，很多同学应该都听说过，比如《愤怒的小鸟》就采用了此引擎。 既然选择了cocos 2d，那么就先继续吹捧下这个框架吧。首先，...</summary><published>2012-03-15T16:45:00Z</published><updated>2012-03-15T16:45:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2399572.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2399572.html"/><content type="html">&lt;p&gt;其实想写cocos2d的东西很久了，一直因为一些乱七八糟的事情，而没有写。前几天跟popple聊天的时候，popple说想要做一些这方面的东西，于是决定还是开始写这一系列的东西吧，记录自己学习，同时也分享给喜欢这个的朋友。&lt;/p&gt;&lt;p&gt;ios上开发游戏有很多方法，最原始的就是用原生的cocoa框架加上OpenGL ES开发，但是这种方法太复杂了，而且操作OpenGL也挺麻烦的，所以我选择了cocos 2d来作为框架开发。这个框架比较简单，而且资料也比较全，内置的box2d引擎，很多同学应该都听说过，比如《愤怒的小鸟》就采用了此引擎。&lt;/p&gt;&lt;p&gt;既然选择了cocos 2d，那么就先继续吹捧下这个框架吧。首先，它是免费的，你用它来做商业开发都没关系，其次，它是开源的，但是现在这点对我不是很重要，因为目前只能做一个伸手党，确实没有太多的能力去贡献cocos 2d社区。最后，也是我选择它最重要的一个原因，就是简单而且文档丰富，遇到的问题，google一下，很多时候，都能找到答案。顺便提一下，现在使用cocos2d还有个额外的好处，就是可以跨平台开发，但是这个不是coos2d实现的，而是一个叫做cocos2dx的项目。cocos2dx可以理解成一个cocos2d的c++版本（因为接口基本上一样），但是它却可以编译成各种平台上的app，非常强大。它的主要贡献者来自中国，大家可以关注下他的&lt;a href="http://weibo.com/walzer" target="_blank"&gt;微博&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;这一系列的文章，是以《Learn iPhone and iPad Cocos2d Game Development》为基础，总结一些书里面的知识以及自己对这些的理解。还请各位大牛多多指点。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2399572.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2012/03/16/2399572.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2012/03/01/2374994.html</id><title type="text">mac下我常用的一些软件</title><summary type="text">在苹果发布了mountain lion的开发者预览版后，我就毫不犹豫的升级了。刚开始的时候，用起来感觉还挺好的，跟ios融合的很好，我在手机上记录的一些东西，在mountain lion中都能立即同步过来。更让我期待的是，新加的通知功能很不错，以后就可以把一些不太重要的消息设置成不弹出来提示，有时间的时候，再去通知中心查看。 但是跟mountain lion过了几天美好的生活后发现，开发者预览版还是不适合做日常的稳定系统，首先就是跟一些软件不兼容，比如大名鼎鼎的虚拟机——PD，其次就是功能有些不太稳定，新版的safari浏览的时候，有时候滑动页面，会出现一些卡顿感，这也是直接导致我装回l...</summary><published>2012-03-01T01:14:00Z</published><updated>2012-03-01T01:14:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2012/03/01/2374994.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2012/03/01/2374994.html"/><content type="html">&lt;p&gt;&lt;span&gt;在苹果发布了mountain lion的开发者预览版后，我就毫不犹豫的升级了。刚开始的时候，用起来感觉还挺好的，跟ios融合的很好，我在手机上记录的一些东西，在mountain lion中都能立即同步过来。更让我期待的是，新加的通知功能很不错，以后就可以把一些不太重要的消息设置成不弹出来提示，有时间的时候，再去通知中心查看。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;但是跟mountain lion过了几天美好的生活后发现，开发者预览版还是不适合做日常的稳定系统，首先就是跟一些软件不兼容，比如大名鼎鼎的虚拟机&amp;mdash;&amp;mdash;PD，其次就是功能有些不太稳定，新版的safari浏览的时候，有时候滑动页面，会出现一些卡顿感，这也是直接导致我装回lion的导火线。&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;这里继续吐槽下苹果，在升级到mountain lion后，发现想退回去太难了，尝试了用网络恢复，结果wifi的部件有问题，老连接不上，不过网上有朋友说，就算连上了，也是直接恢复成新版的mountain lion，那又有什么意义呢?然后借用了boris在lion下做的恢复盘，发现也没办法恢复，最后只能自己重新做了一个lion的安装U盘，这才搞定。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;不过这样转了一大圈，也有好处，一是体验了下新的系统，二来，也重新梳理了下mac里我常用的一些软件：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;1、iterm 2：非常好用的终端，完全可以替代系统自带的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;2、Eclipse：我主要是把它当做c/c++的编辑器。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;3、Secure CRT：用来登陆远程的服务器。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;4、xcode：苹果自己的IDE，装完后，gcc这些也就自动装好了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;5、搜狗输入法：以前一直用QQ拼音，但是后来发现在长词组上，搜狗还是好很多。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;6、the unarchiver：mac store上免费的解压软件。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;7、MPlayerX：很不错的视频播放器，类比与windows平台的QQ影音。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;8、totalfinder：可以简单的把它当做有标签的finder，但是我最喜欢的是可以用快捷键呼出，就像在windows里面使用win+e一样。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;9、dropbox：同步不同电脑、手机里面的文件，主要是上传和下载速度非常快，我使用中上传和下载最快都有400k/s。不过由于某东西的存在，用dropbox一直不太安心。等金山快盘出了mac版后，准备先试试金山的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;10、evernote：记录笔记。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;11、ipuff：这个就是翻越某物体的，买个商业版的账号，很稳定。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;12、reeder：我最喜欢的rss客户端&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;13、Microsoft Office和iWork：这个应该不用多说，都会装吧。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;14、iPhoto：主要是要使用icloud的照片流功能。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;15、QQ&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;16、有道词典：在mac下其实有更好的，或者就用自带的也行，但是windows下习惯了有道，而且也对网易有信心，所以选择了这个，不过本地词库太弱了，没有网络，基本上等于不能用。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;17、brew：这个要强烈推荐下，因为在ubuntu下习惯了apt，所以装软件的生活，总是习惯了apt-get install ***，这个软件让你在mac下也能在终端下装软件，使用起来也非常简单，比如brew install ***&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;18、synergy：如果你有几台电脑，又不想用几套键鼠，那么这个虚拟的切换器能帮你做到，非常推荐。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;19、Scroll Reverser：在lion下，触摸板和鼠标的滚轮方向是绑死的，要么是传统的方式，要么是iphone一样的自然方式，但是我比较喜欢触摸板使用自然方式，而鼠标依旧使用传统模式，所以，这个软件就很有必要了&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2374994.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2012/03/01/2374994.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2012/01/16/2324108.html</id><title type="text">google proto buffer使用</title><summary type="text">听说google proto buffer（以下简称protobuf）已经很久了，但是一直没有尝试使用它。其中一个原因是，项目组自己写了个打包和解包的工具，而且代码也简单，可以很方便的扩展到自动生成xml之类的配置文件，已经能很好的符合项目的需要。但是最近发现protobuf有个很不错的功能，就是可以向已有的协议中添加新的字段，而不影响采用旧协议的服务。所以就想试试protobuf。 要使用google proto buffer，首先要进行的就是安装，先说说我的（mac os X 10.7.2）安装过程吧： 1、下载google proto buff。 2、解压下载的包，并且阅读R...</summary><published>2012-01-16T13:44:00Z</published><updated>2012-01-16T13:44:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2012/01/16/2324108.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2012/01/16/2324108.html"/><content type="html">&lt;p&gt; 听说google proto buffer（以下简称protobuf）已经很久了，但是一直没有尝试使用它。其中一个原因是，项目组自己写了个打包和解包的工具，而且代码也简单，可以很方便的扩展到自动生成xml之类的配置文件，已经能很好的符合项目的需要。但是最近发现protobuf有个很不错的功能，就是可以向已有的协议中添加新的字段，而不影响采用旧协议的服务。所以就想试试protobuf。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;要使用google proto buffer，首先要进行的就是安装，先说说我的（mac os X 10.7.2）安装过程吧：&lt;/p&gt;&lt;p&gt;1、&lt;a href="http://code.google.com/p/protobuf/downloads/list" target="_blank"&gt;下载&lt;/a&gt;google proto buff。&lt;/p&gt;&lt;p&gt;2、解压下载的包，并且阅读README.txt，根据里面的指引进行安装。&lt;/p&gt;&lt;p&gt;3、&amp;nbsp;$ ./configure&lt;/p&gt;&lt;p&gt;$ make&lt;/p&gt;&lt;p&gt;$ make check&lt;br /&gt; $ make install&lt;/p&gt;&lt;p&gt;没有意外的话，前面三步应该都能顺利完成，第四步的时候，需要root权限。我采用的默认的路径，所以，仅仅用root权限，还是安装不了，要自己先在/usr/local下新建一个lib的目录，然后执行make install，这样，应该就能顺利安装google proto buffer了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;安装完后，先写一个测试程序来测试下安装，先来看看proto文件：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('289af40f-f625-4693-aebf-6f80e5da8d53')"&gt;&lt;div id="cnblogs_code_open_289af40f-f625-4693-aebf-6f80e5da8d53" class="cnblogs_code_hide"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; package hello;&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; message Hello{&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;     required int32      id      = &lt;span style="color: #800080;"&gt;1&lt;/span&gt;;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;user id&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;     required &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;     name    = &lt;span style="color: #800080;"&gt;2&lt;/span&gt;;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;user name&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt;     optional &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;     email   = &lt;span style="color: #800080;"&gt;3&lt;/span&gt;;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;user email&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;接着，要用protoc生成一个对应的类，我把它生成在./out目录里：&lt;/p&gt;&lt;p&gt;protoc hello.proto --cpp_out=./out&lt;/p&gt;&lt;p&gt;接下来，在out目录下，会生成两个文件:&lt;/p&gt;&lt;p&gt;$&amp;gt; ls&lt;/p&gt;&lt;p&gt;hello.pb.cc hello.pb.h&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;接下来，编写测试用的c++代码：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('76bcbb71-50fc-40e2-b46a-8861f0e16e63')"&gt;&lt;div id="cnblogs_code_open_76bcbb71-50fc-40e2-b46a-8861f0e16e63" class="cnblogs_code_hide"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; #include &amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;.h&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; #include &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;out/hello.pb.h&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; std;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; hello;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; main()&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;     Hello a;&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;     a.set_id(&lt;span style="color: #800080;"&gt;101&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;     a.set_name(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangwei&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; tmp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; ret = a.SerializeToString(&amp;amp;tmp);&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (ret) &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         printf(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;encode success!\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;         printf(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;encode faild!\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;     Hello b;&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;     ret = b.ParseFromString(tmp);&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (ret)&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         printf(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;decode success!\n id= %d \n name = %s\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, b.id(), b.name().c_str());&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;         printf(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;decode faild!\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;接着，编译一下这个代码，由于使用了protobuf的库，所以编译的时候，要把这些库也链接进来：&lt;/p&gt;&lt;p&gt;&amp;nbsp;g++ hello.cc ./out/hello.pb.cc -o hello -I./out -I/usr/local/protobuf/include -L/usr/local/lib -lprotobuf&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这样，就生成了测试程序。&lt;/p&gt;&lt;p&gt;运行一下：&lt;/p&gt;&lt;p&gt;$&amp;gt; ./hello &lt;br /&gt;encode success!&lt;br /&gt;decode success!&lt;br /&gt; id= 101 &lt;br /&gt; name = huangwei&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这样，简单的google proto buffer的使用就完成了。有什么错误的地方，还请各位斧正。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2324108.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2012/01/16/2324108.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2011/12/11/2284271.html</id><title type="text">android，说好的公正</title><summary type="text">昨天晚上发微博，说自己欠android一个公正，今天要写一片文章来公正的谈谈android。 其实，坦白来说，我算不上一个android黑，反而还是偏android粉一点，但是最近在跟人聊天的时候，或多或少贬低了下android，或许，这应该描述成恨铁不成钢比较何时吧。本文就从G1开始将起我和android的故事吧。 09年的时候，恰好想换台手机，于是就选择了htc的G1，当时对android甚至智能机都没什么太大的概念，只是觉得做的方向是linux方面的东西，不如干脆买台android来体验下。于是入手了英国版的G1，全名叫HTC Dream。机如其名，现在回想起来，也觉得买G1是一...</summary><published>2011-12-11T14:48:00Z</published><updated>2011-12-11T14:48:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2011/12/11/2284271.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2011/12/11/2284271.html"/><content type="html">&lt;p&gt;&lt;span&gt;昨天晚上发微博，说自己欠android一个公正，今天要写一片文章来公正的谈谈android。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;其实，坦白来说，我算不上一个android黑，反而还是偏android粉一点，但是最近在跟人聊天的时候，或多或少贬低了下android，或许，这应该描述成恨铁不成钢比较何时吧。本文就从G1开始将起我和android的故事吧。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;09年的时候，恰好想换台手机，于是就选择了htc的G1，当时对android甚至智能机都没什么太大的概念，只是觉得做的方向是linux方面的东西，不如干脆买台android来体验下。于是入手了英国版的G1，全名叫HTC Dream。机如其名，现在回想起来，也觉得买G1是一个很明智的决定。到手的时候，很激动的直奔宿舍。体验了下，感觉划屏的时候有点卡，但是其他的地方就感觉跟梦幻一样，很多东西都很新鲜，跟其他的手机完全不是一个档次的（当时还没玩过ios）。接下来的事情，估计很多android手机用户都应该能猜到，那就是刷机，于是各种小白贴，怎么解锁、怎么刷recovery，怎么刷rom，忙得不亦乐乎。那个时候比较有名的rom是啊兴和蛋蛋的。我个人刷啊兴的比较多。记得手机刚刷了啊兴的rom后，比刚拿回来的时候，流畅了不少，那个时候，对啊兴就很仰慕。最开始的时候，最热门的两个论坛是安卓网和机锋网，啊兴的主战场好像是安卓网，而蛋蛋主要活跃在机锋网，后来啊兴去了N多网，于是我也跟着转向了N多网，不过没有坚持多久。因为啊兴去了N多后不久，我又换了台手机，于是跟G1系列的rom就告别了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;android其实本质上就是一个山寨的ios，只不过其在google名下，所以质疑的声音就没那么大，估计如果是国内某家厂商推出的，论坛上会被骂得狗血淋头，这也算是天朝网络的一大奇观，君不见cnbeta上，无论内容是什么，喷子先开骂，好了，不扯这个了，毕竟不是本文主题。看了关于android的一些历史，原本android是为有键盘的手机设计的，但是iphone推出后，团队觉得这种设计确实不错，于是就改成了我们现在看到的android。但是由于这种操作体验不是源自自身，所以在很多方面理解得不够透彻，所以很多地方做得不够好，但是为了打出市场，也进行了不少创新，比如通知栏等。那么通过对比来看看我认为的android的一些优缺点（主要相对ios来说）吧：&lt;/p&gt;&lt;p&gt;先看看优点&lt;/p&gt;&lt;p&gt;１、通知栏&lt;/p&gt;&lt;p&gt;通知栏算是android两个最大的亮点之一吧，创新的下拉式通知，将所有的信息都陈列于此，简单而且实用，从ios 5向android致敬就能看出。&lt;/p&gt;&lt;p&gt;2、桌面插件&lt;/p&gt;&lt;p&gt;这个是另外一个大亮点，也是ios和wp没有的。widget确实很实用，比如你可以把日历放到桌面上，这样你只要打开桌面，不用进入应用就能看到接下来的行程安排。此处多说一句，插件如果随意摆放，就会使桌面看起来非常凌乱，我个人比较讨厌这样，所以一般我只放少数几个widget。不过这个只和个人习惯有关，和系统无关。ios 5也开始慢慢领悟这个，虽然没有插件，但是可以把一些类似天气的widget直接放到通知栏，已经能代替绝大部分的桌面插件，我个人还是比较喜欢这样的设计的。&lt;/p&gt;&lt;p&gt;3、google服务&lt;/p&gt;&lt;p&gt;在使用了android后，才发现google服务整合手机有多么好用。我想如果没有google的服务，我刷机的频率会小很多，因为每刷一次机，你就需要重新整理通信录等。不过如果你平时不怎么用google的服务，比如日历、gmail等，那么，这一条你可以忽略了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;再来说说缺点吧：&lt;/p&gt;&lt;p&gt;1、效率&lt;/p&gt;&lt;p&gt;一个很简单的例子，就拿植物大战僵尸这款游戏来说，在ios上，就算是1代的touch，只有400MHz的，依然能非常流畅的运行这款游戏，而且操作体验非常好，而在android上，就算是G7这样的后来者，也只能望洋兴叹。还有就是滑动的体验，android有时候会感觉有点卡顿，而ios基本上是很顺滑。&lt;/p&gt;&lt;p&gt;2、电源管理&lt;/p&gt;&lt;p&gt;网上流传的一个笑话是，用android的男人都是好男人，因为他每天晚上必须回去充电。可能很多人会说，iphone不也一样？但是如果你用过iphone后，你就会发现，好的还真不是一点两点，开开wifi听歌就知道了。&lt;/p&gt;&lt;p&gt;3、应用商店&lt;/p&gt;&lt;p&gt;其实这个是我觉得最大的问题所在。android的应用商店跟app store还是有很大的差距，这个差距不是应用程序的数量，而是质量。比如zaker这样的浏览体验，在android上就没法得到有效的体现，顺滑的切屏，极速的响应，这些并不是简单的通过硬件升级就能体现的。而且android市场有点轮乱，什么样的软件都有，甚至连病毒都能发布，google这样的开放，给普通用户带来了很大的困扰，就好比消费者去国美买电器，如果电器出了问题，消费者会觉得是谁的问题，而且如果买的出问题的产品多了，谁还会信任这个商店？相比较而言，苹果和微软在这个事情上的态度就比较一致。个人感觉，在移动平台，封闭系统可能会更好。&lt;/p&gt;&lt;p&gt;4、缺乏艺术性&lt;/p&gt;&lt;p&gt;当然，每个人的审美观不一样，对艺术的品味也不一样。反正我用源生android的时候，就总感觉其怪怪的，整体的配色什么都不是很舒服。这也是为什么htc sence和miui会被很多人喜欢的原因。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;大大小小说了这么多，也和朋友讨论过很多，总体看来，android的开放性让你有更多的选择，如果你觉得这个不好，你可以换个rom，说不定就解决了。但是一路刷下来后，到最后，你觉得厌倦了，这个时候，你想找一个合适的rom，然后你突然发现，原来这种rom是不存在的。不过我个人还是挺喜欢android的，因为它让更多的人用得起智能手机，让更多的人愿意来尝试智能手机，而且，多一个选择，很多时候都是好的。通过google和其他厂商几年来不断的改进，android整个系统也越来越完善，不再仅仅只是向IOS致敬，而有了自己的风格，也希望android以后能给我们带来更多的惊喜。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;最后说说我对这几款系统的看法，如果你想选择一台智能机，那么现在你的首选应该android，因为款式多，各个档次的都有，我比较推荐小米手机，虽然在参数上有点错误引导性，但是它的价格还是很厚道的，而且有miui做后盾，比较适合一般预算的人入手。但是如果你不想太折腾，同时又不差钱，那么，iphone是你很好的选择。而如果厌倦了android，又不喜欢iphone，那么尝试下windows phone吧，风格很不错，应用也在慢慢增多，前景看好。不过你可能要做好心里准备，用的时间长了，会觉得metro有点单调，至少从我个人的使用情况看是这样的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;好吧，不知道各位觉得这篇文章是否公正？如果有什么错误，也请各位斧正，谢谢拉。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2284271.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2011/12/11/2284271.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2011/11/17/2253333.html</id><title type="text">创造生活，创造快乐</title><summary type="text">很久没写博客了，看了下最新更新的博客还是4月份的，很是惭愧。看到很多朋友在博客里面留言，最近的大部分留言基本上都是围绕我LSM那篇文章的。在国内，确实关于这一方面的东西还是比较少的，所以也很能理解大家的心情。LSM是我毕业设计所研究的对象，本来是想在论文提交后总结下，然后分享给大家的，但是那段时间享受毕业季去了，所以一直没写。现在偶尔想写，但是又觉得没有对这个没有激情了，所以也不打算计继续写LSM相关的文章，还请各位见谅。 虽然不打算继续写LSM方面的文章，但是还是把一些最基本的思路跟大家分享一下。其实LSM最简单的理解就是一组钩子函数（hook），它几乎存在在内核的每一个子系统里面...</summary><published>2011-11-17T15:21:00Z</published><updated>2011-11-17T15:21:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2011/11/17/2253333.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2011/11/17/2253333.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 很久没写博客了，看了下最新更新的博客还是4月份的，很是惭愧。看到很多朋友在博客里面留言，最近的大部分留言基本上都是围绕我LSM那篇文章的。在国内，确实关于这一方面的东西还是比较少的，所以也很能理解大家的心情。LSM是我毕业设计所研究的对象，本来是想在论文提交后总结下，然后分享给大家的，但是那段时间享受毕业季去了，所以一直没写。现在偶尔想写，但是又觉得没有对这个没有激情了，所以也不打算计继续写LSM相关的文章，还请各位见谅。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 虽然不打算继续写LSM方面的文章，但是还是把一些最基本的思路跟大家分享一下。其实LSM最简单的理解就是一组钩子函数（hook），它几乎存在在内核的每一个子系统里面，如果你想要实现某一部分的功能，其实只需要找到对应的函数，然后重新编写就行了。比如你想控制root的权限，那么可以在执行命令的时候，检查一下该用户的id，然后采取相应的策略。首先可以去看下exec簇函数的源代码，然后一层一层的找到里面跟安全机制相关的函数，最后你会发现LSM已经提前预留了钩子在里面，然后利用该函数编写一个模块，再接着插入内核，就应该可以了。在编写的过程中，错误难免，你可能会遇到插入模块，然后机器就各种诡异，最后必须重启来解决。不用担心，多打点日志，dmesg一下，你离成功就越来越近了。susu现在还在继续研究这个方向，前段时间听说她签的工作，就是这个系统的甲方。调侃了一下她，明明有很多待遇更好的公司，为什么偏偏选择了这一家。她的答案很简单，就是喜欢。也正因为这样，更加佩服她，难怪陈老师为有这样的女弟子而自豪。下次鼓动下她多写写这方面的文章，跟需要的朋友分享下。到时候，我会第一时间放上链接。susu博客&lt;a href="http://home.lupaworld.com/home-space-uid-401174-do-blog-view-me-from-space.html" target="_blank"&gt;链接&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;前段时间adobe宣布放弃移动平台的flash插件，当时跟几个朋友一起讨论了下，他们都还觉得flash在很多方面还是有优势的，还是能继续霸占市场的。但是我觉得，以后的方向应该是W3C的html，标准的形成，从来都是跟大公司的支持分不开的，apple、google、microsoft、facebook都表态支持html 5，那么，还有什么好说的呢？希望园子里的朋友能多创造优秀的html 5的应用，为html 5的普及添砖加瓦。看过以前园子里面关于java跟C#的论战，很怕，所以这个话题就此打住吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 对很多技术其实都很感兴趣，但是还是决定关注在两个方面，一个是linux，另一个就是ios。之所以选择这两个方向，其实都是出于喜欢，从刚进大学的时候，就接触了linux，学校的linux兴趣小组在国内开源社区还是小有名气的（虽然最终也没加入这个小组，但是觉得这个小组的气氛应该该是学校里面最好的），接着跟着陈老师从linux系统编程，慢慢进入内核领域，虽然在内核源码上面只是浅尝而止，但是却了解了内核运行的很多方面。在这里也要感谢下陈老师，个人觉得其是我们学校最优秀的教师，其从事linux内核开发10余年，学术渊博，但是最令人佩服的地方，就是能够引导学生的兴趣，支持大家做自己喜欢的事情。很多时候，都是站在学生角度出发，顶住上面的压力，推行实用主义改革。这样的精神在官僚思想横行的大学校园，鹤立鸡群。再次感谢陈老师。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;关于ios方面，其实垂涎很久了，以前还折腾了好久，最终在PC上装上了mac。说到垂涎，倒不是看到其开发者分成，只是喜欢这样的平台，简洁，流畅。我从G1开始使用android，应该算的上国内第一批android粉丝了，那个时候，在同学的touch上玩过ios上的游戏，觉得非常流畅，但是只是觉得android是开源的，所以就没关注ios这样的封闭系统。后来受到retina屏幕的影响，决定入手apple的产品。由于还不想换掉android手机，所以去年没有入手iphone 4，而是选择了刚刚发布的touch 4。整体感受下来，还是ios更胜一筹，流畅度以及应用的质量，比android好太多了。于是开始喜欢上苹果，说实话，觉得乔布斯还真的是改变世界的天才。从现在用的macbook air上就能很强烈的感受到，这真的是笔记本的未来。对于ios平台上的开发，其实更多的是自己的兴趣，如果能让这个世界更加美好，why not？创造生活，创造快乐。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2253333.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2011/11/17/2253333.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2011/04/15/2017376.html</id><title type="text">简单的时间服务程序</title><summary type="text">这个系列的文章主要是学习《UNIX 网络编程（卷一：套接字联网API）》的一些学习札记。 先看下这个简单的从服务器获取时间的客户端程序：#include &lt;stdio.h&gt;#include &lt;stdlib.h&gt;#include &lt;string.h&gt;#include &lt;unistd.h&gt;#include &lt;error.h&gt;#include &lt;sys/types.h&gt;#include &lt;sys/socket.h&gt;#include &lt;netinet/in.h&gt;#include &lt;arpa/inet.</summary><published>2011-04-15T09:02:00Z</published><updated>2011-04-15T09:02:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2011/04/15/2017376.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2011/04/15/2017376.html"/><content type="html">&lt;p&gt;这个系列的文章主要是学习《UNIX 网络编程（卷一：套接字联网API）》的一些学习札记。&lt;/p&gt;&lt;p&gt;先看下这个简单的从服务器获取时间的客户端程序：&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br/&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br/&gt;#include &amp;lt;string.h&amp;gt;&lt;br/&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br/&gt;#include &amp;lt;error.h&amp;gt;&lt;br/&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;br/&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br/&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br/&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;int main(int argc, char **argv)&lt;br/&gt;{&lt;br/&gt;    int sock_fd;&lt;br/&gt;    struct sockaddr_in sock_addr;&lt;br/&gt;&lt;br/&gt;//  检查传入的参数是否正确&lt;br/&gt;    if(argc &amp;lt; 2) {&lt;br/&gt;        printf("usage:time_client &amp;lt;IPAddress&amp;gt;");&lt;br/&gt;        return -1;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;//  建立socket&lt;br/&gt;    sock_fd = socket(AF_INET, SOCK_STREAM, 0);&lt;br/&gt;    if(sock_fd &amp;lt; 0) {&lt;br/&gt;        perror("socket:");&lt;br/&gt;        return -1;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;//  设置需要连接的服务器的IP和端口号&lt;br/&gt;    bzero(&amp;amp;sock_addr, sizeof(sock_addr));&lt;br/&gt;    sock_addr.sin_family = AF_INET;&lt;br/&gt;    sock_addr.sin_port = htons(3000);&lt;br/&gt;    inet_pton(AF_INET, argv[1], &amp;amp;sock_addr.sin_addr);&lt;br/&gt;&lt;br/&gt;//  连接服务器&lt;br/&gt;    if(connect(sock_fd, (struct sockaddr *)&amp;amp;sock_addr, sizeof(sock_addr)) &amp;lt; 0) {&lt;br/&gt;        perror("connect:");&lt;br/&gt;        return -1;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;//  从服务器端获取信息&lt;br/&gt;    char buff[1024];&lt;br/&gt;    int read_count;&lt;br/&gt;    while( (read_count = read(sock_fd, buff, sizeof(buff))) &amp;gt; 0) {&lt;br/&gt;        buff[read_count] = '\0';&lt;br/&gt;        printf("read string : %s\n");&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    return 0;&lt;br/&gt;}&lt;br/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;1、首先用socket函数创建一个网际（AF_INET）字节流（SOCK_STREAM）套接字，该函数返回一个文件描述符，接下来的步骤都会用到这个返回的文件描述符。&lt;/p&gt;&lt;p&gt;2、连接服务器。这个首先要让程序知道服务器的地址和端口号，这就要用到一个struct sockaddr_in的网络套接字地址结构，因为有少数套接字函数要求网际套接字地址结构的最后8个字节置零（具体是哪几个函数，以后看到再补上），所以需要首先用bzero将struct sockaddr_in置零。在这里，ip地址和端口号不能按照常见的形式填入结构体里面，对于端口号，必须将其从主机序转换为网络序，这里要用到htons(host to net short)这个函数，ip地址则要将其从我们常见的写法转换成机器能识别的写法，并且将其转换为网络序，这里调用inet_pton来实现，该函数支持IPV6。设置完这些基本的信息后，就可以使用connect函数来连接服务器了。&lt;/p&gt;&lt;p&gt;3、读取时间信息。因为linux将所有的设备抽象成文件，所以，读取套接字的信息就可以像读取本地文件一样，使用read就可以了。&lt;/p&gt;&lt;p&gt;再接着看看服务器端的程序：&lt;/p&gt;&lt;p&gt;这个程序和客户端程序的差别主要是几个地方：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br/&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br/&gt;#include &amp;lt;string.h&amp;gt;&lt;br/&gt;#include &amp;lt;time.h&amp;gt;&lt;br/&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br/&gt;#include &amp;lt;error.h&amp;gt;&lt;br/&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;br/&gt;#include &amp;lt;sys/socket.h&amp;gt;&lt;br/&gt;#include &amp;lt;netinet/in.h&amp;gt;&lt;br/&gt;#include &amp;lt;arpa/inet.h&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;int main(int argc, char **argv)&lt;br/&gt;{&lt;br/&gt;//  建立套接字&lt;br/&gt;    int server_fd;&lt;br/&gt;    server_fd = socket(AF_INET, SOCK_STREAM, 0);&lt;br/&gt;    if(server_fd &amp;lt; 0) {&lt;br/&gt;        perror("socket:");&lt;br/&gt;        return -1;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;//  设置套接字结构体&lt;br/&gt;    struct sockaddr_in sock_addr;&lt;br/&gt;    bzero(&amp;amp;sock_addr, sizeof(sock_addr));&lt;br/&gt;    sock_addr.sin_family = AF_INET;&lt;br/&gt;    sock_addr.sin_port = htons(3000);&lt;br/&gt;    sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);&lt;br/&gt;&lt;br/&gt;//  bind套接字&lt;br/&gt;    if( (bind(server_fd, (struct sockaddr *)&amp;amp;sock_addr, sizeof(sock_addr))) &amp;lt; 0) {&lt;br/&gt;        perror("bind");&lt;br/&gt;        return -2;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;//  将套接字转换为监听套接字&lt;br/&gt;    if (listen(server_fd, 1024) &amp;lt; 0) {&lt;br/&gt;        perror("listen");&lt;br/&gt;        return -3;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;//  接受连接请求,并发送服务器上的时间&lt;br/&gt;    int connect_fd;&lt;br/&gt;    char buff[1024];&lt;br/&gt;    time_t current_time;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    while(1) {&lt;br/&gt;        connect_fd = accept(server_fd, (struct sockaddr *)NULL, NULL);&lt;br/&gt;        current_time = time(NULL);&lt;br/&gt;        snprintf(buff, sizeof(buff), "%s \n", ctime(&amp;curren;t_time));&lt;br/&gt;        write(connect_fd, buff, strlen(buff));&lt;br/&gt;&lt;br/&gt;        close(connect_fd);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    return 0;&lt;br/&gt;}&lt;br/&gt;&lt;/div&gt;&lt;p&gt;1、bind。这个函数用于将服务器对外服务的端口绑定到套接字上，同时指定了IP地址为INADDR_ANY，通过设置该参数，可以设定服务器是从所有的网络接口上接收客户连接还是从指定的单个网络接口上接受客户端连接。&lt;/p&gt;&lt;p&gt;2、listen。这个函数把套接字转换成一个监听套接字，这样，来自客户的外来连接就可在该套接字上由内核接受。它的第二个参数用于指定系统内核允许在这个监听描述符上排队的最大客户连接数。&lt;/p&gt;&lt;p&gt;3、accept。服务器进程在调用这个函数后会进入睡眠状态，直到内核收到某个客户的连接请求。&lt;/p&gt;&lt;p&gt;4、写入时间信息。在接收客户端连接后，会得到一个这个连接的文件描述符，往这个描述符里面写入信息就可以了。&lt;/p&gt;&lt;p&gt;上面就是一个简单的时间服务的客户端和服务器的简单实现，如果其中有什么不对的地方，还请您斧正。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/2017376.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2011/04/15/2017376.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2011/01/01/1923891.html</id><title type="text">利用LSM实现更安全的linux</title><summary type="text">LSM的全称是Linux Security Modules，它是linux内核中用来支持更灵活的安全策略的一个底层框架，虽然听起来比较复杂，但是可以就把它理解成一组安插在linux内核的钩子函数和一些预留的被称为安全域的数据结构，下面先说说这个框架的由来吧。linux本身的机制就保证了linux拥有更好的安全机制，但是在这个机制下面，还是隐藏了许多的问题：1、权限粒度太大。用过linux的人应该对0644这样的访问权限设置不陌生，它对能够操作这个文件的用户做了限制，但是这个只是限制到了组，而没有更进一步的细分，当然，如果LSM只是用来限制这个的话，那么也就太没意思了，因为实现文件更细的</summary><published>2011-01-01T13:53:00Z</published><updated>2011-01-01T13:53:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2011/01/01/1923891.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2011/01/01/1923891.html"/><content type="html">&lt;p&gt;LSM的全称是Linux Security Modules，它是linux内核中用来支持更灵活的安全策略的一个底层框架，虽然听起来比较复杂，但是可以就把它理解成一组安插在linux内核的钩子函数和一些预留的被称为安全域的数据结构，下面先说说这个框架的由来吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;linux本身的机制就保证了linux拥有更好的安全机制，但是在这个机制下面，还是隐藏了许多的问题：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1、权限粒度太大。用过linux的人应该对0644这样的访问权限设置不陌生，它对能够操作这个文件的用户做了限制，但是这个只是限制到了组，而没有更进一步的细分，当然，如果LSM只是用来限制这个的话，那么也就太没意思了，因为实现文件更细的控制粒度，ACL就能够很出色的完成，顺便提一下，ACL有一个分配的限制，如果哪位朋友需要用ACL进行粒度更细的访问权限控制的话，可能需要注意一下这方面的东西。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、root用户的权限太大。在linux中，root用户就是至高无上的，他拥有对机器的完全控制权限，可以做他想做的一切事情。但是很多时候，我们可能并不希望有root有这么大的权限，比如在现在比较流行的云存储中，用户肯定不希望服务提供商能够随意访问我们的文件，那么这个时候，就需要对root用户进行一定的设置了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;由于这些问题的存在，所以出现了像SE Linux(Securiy Enhanced Linux )这样的增强补丁。但是每个系统对于具体安全细节的控制不尽相同， 所以Linus Tovalds&amp;nbsp;提出应该要有一个 Linux 内核所能接受的安全框架来支持这些安全策略，这个安全框架应该提供包含内核数据结构中的透明安全域以及用来控制、维护安全域操作的安全钩子，于是就有了LSM。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;LSM在内核中的位置，可以用下图来表示（注：这张图是我从网上找的，因为它确实很清晰地体现了LSM的位置，所以直接拿来使用了，因为现在不知道这张图的原出处，如果冒犯了您的权益，请告诉我，我马上删除，谢谢啦，呵呵）：&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" src="http://pic002.cnblogs.com/images/2011/121543/2011010121095078.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;当用户态程序调用某些操作系统提供的函数的时候，比如read()函数，其会对应于内核中的一个系统调用，然后该首先会进行一些常规的错误检测，接着进行DAC（Discretionary Access Control）检测，再接着它会进行LSM检测。从上图中能够看出来，LSM其实是一个非常底层的安全策略框架，利用LSM，可以接管所有的系统调用，这样，我们就能对包括root在内的所有用户的权限进行控制，并且实现粒度更细的访问权限控制。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;当系统初始化的时候，LSM就是一个空的框架，它不提供任何的检测，其所做的全部工作几乎就是返回0，当然，有些不带返回值的函数除外。而我们则可以针对自己特定的需求来编写LSM，然后将我们编写的LSM钩子函数，通过其数据结构struct security_operations注册到系统中去，这样，我们的LSM检测就开始起作用了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在接下来的文章中，会通过项目中的一个部分&amp;mdash;&amp;mdash;限制root用户对某些文件的访问权限来更具体的说明LSM这个框架，当然，略陈固陋，还请各位大牛多多指教，谢谢啦。呵呵&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/1923891.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2011/01/01/1923891.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2010/09/24/1834017.html</id><title type="text">利用信号实现写优先的读写锁</title><summary type="text">以前利用linux系统提供的读写锁写过一些小程序，但是linux系统提供的读写锁是线程级的，如果是进程间的同步的话，就没那么轻松了。而且由于linux系统提供的读写锁是读优先的，在有些情况下，也不能满足我们的要求。下面就说说利用信号量来实现写优先的读写锁。先说说原理，这个程序需要用到两个信号量，一个互斥信号量A，一个同步信号量B，其拥有MAX_RESOURCES个资源。当读进程申请读锁的时候，...</summary><published>2010-09-24T09:41:00Z</published><updated>2010-09-24T09:41:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2010/09/24/1834017.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2010/09/24/1834017.html"/><content type="html">&lt;div class="Section0"&gt;&lt;p class="p0"&gt;以前利用linux系统提供的读写锁写过一些小程序，但是&lt;span style="font-family: Times New Roman;"&gt;linux&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;系统提供的读写锁是线程级的，如果是进程间的同步的话，就没那么轻松了。而且由于&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;linux&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;系统提供的读写锁是读优先的，在有些情况下，也不能满足我们的要求。下面就说说利用信号量来实现写优先的读写锁。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;先说说原理，这个程序需要用到两个信号量，一个互斥信号量&lt;span style="font-family: Times New Roman;"&gt;A&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，一个同步信号量&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;B&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，其拥有&lt;/span&gt;MAX_RESOURCES个资源。当读进程申请读锁的时候，首先查看是否已经有写进程申请了&lt;span style="font-family: Times New Roman;"&gt;A&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源，如果有，则进入阻塞状态，否则，则申请一个&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;B&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源，等读操作完成后，再释放&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;B&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源。当写进程申请写锁时，首先查询是否已经有其他的写进程已经申请了&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;A&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源，如果有，则进入阻塞状态，否则，先申请&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;A&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源，然后申请&lt;/span&gt;MAX_RESOURCES个&lt;span style="font-family: Times New Roman;"&gt;B&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源，这样，如果有读进程正在执行读操作，那么写进程就会阻塞，直到所有的读进程都释放&lt;/span&gt;&lt;span style="font-family: Times New Roman;"&gt;B&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;资源。通过这样的机制，就保证了这是一个写优先的读写锁。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;下面是一些关键代码：&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;读锁：&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置读锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_num &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;判断信号量0是否为0&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_op &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_num &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;对信号量1进行P操作&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_op &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;_r_lock[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SEM_UNDO;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestRWLock::TestRLock()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; semop(_sem_fd, _r_lock, &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;写锁：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="width: 735px; height: 679px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置写锁&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;判断信号量是否为0，如果是，则对其进行+1操作&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_num &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_num &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_op &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_first[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SEM_UNDO;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;申请信号量1所有的资源，这样能保证所有的读锁都已经释放资源_w_lock_second.sem_num = 1;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_second.sem_op &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; max_reader;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;_w_lock_second.sem_flg &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SEM_UNDO;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestRWLock::TestWLock()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; semop(_sem_fd, _w_lock_first, &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ret &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;        ret &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; semop(_sem_fd, &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;_w_lock_second, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ret &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;            ANGEL_WARN_LOG(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;加写锁失败&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #000000;"&gt;    } &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #000000;"&gt;        ANGEL_WARN_LOG(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;加写锁失败.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ret;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/1834017.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2010/09/24/1834017.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangwei/archive/2010/09/15/1826645.html</id><title type="text">google C/C++编程风格的一些摘要</title><summary type="text">前段时间看了下google c/c++编程风格，摘录一些要点记载于此，还请各位指点。为了接下来清楚的阐述googleC++编程规范，先阐述几个概念：PascalCase：当标识符由两个或者两个以上单词组成的时候，单词之间不加其他的符号，并且每个单词都必须大写，例如PascalCase。camelCase:当标识符由两个或者两个以上单词组成的时候，单词间不加其他的符号，并且第一个单词以小...</summary><published>2010-09-15T01:18:00Z</published><updated>2010-09-15T01:18:00Z</updated><author><name>MR_H</name><uri>http://www.cnblogs.com/huangwei/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangwei/archive/2010/09/15/1826645.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangwei/archive/2010/09/15/1826645.html"/><content type="html">&lt;p class="p0"&gt;前段时间看了下google c/c++编程风格，摘录一些要点记载于此，还请各位指点。&lt;/p&gt;&lt;p class="p0"&gt;为了接下来清楚的阐述&lt;span style="font-family: 'Times New Roman';"&gt;google&amp;nbsp;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;编程规范，先阐述几个概念：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;Pascal&amp;nbsp;Case&amp;nbsp;&lt;/strong&gt;：当标识符由两个或者两个以上单词组成的时候，单词之间不加其他的符号，并且每个单词都必须大写，例如PascalCase。&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;camel&amp;nbsp;Case&lt;/strong&gt;:&amp;nbsp;当标识符由两个或者两个以上单词组成的时候，单词间不加其他的符号，并且第一个单词以小写开头，其他单词以大写开头。例如camelCase。&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;Unix/Linux&lt;span style="font-family: 宋体;"&gt;变量命名方法&lt;/span&gt;&lt;/strong&gt;：当程序由两个或两个以上单词组成的时候，单词都以小写开头，并且以_连接。&amp;nbsp;&lt;/p&gt;&lt;p class="p0"&gt;下面是&lt;span style="font-family: 'Times New Roman';"&gt;Google&amp;nbsp;C++&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;编程规范的一些内容：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;一、命名&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;1）普通变量：&lt;span style="font-family: 'Times New Roman';"&gt;linux&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;命名规范&lt;/span&gt;&amp;nbsp;。例如：&lt;span style="font-family: 'Times New Roman';"&gt;string&amp;nbsp;&lt;/span&gt;table_name;&lt;/p&gt;&lt;p class="p0"&gt;2）常量：&amp;nbsp;&lt;span style="font-family: 'Times New Roman';"&gt;k+&lt;/span&gt;PascalCase。例如&amp;nbsp;const&amp;nbsp;int&amp;nbsp;kDayInAWeek&amp;nbsp;=&amp;nbsp;7;&lt;/p&gt;&lt;p class="p0"&gt;3）类私有成员：&amp;nbsp;linux命名规范&lt;span style="font-family: 'Times New Roman';"&gt;+&lt;/span&gt;_。&amp;nbsp;例如：&lt;span style="font-family: 'Times New Roman';"&gt;int&lt;/span&gt;&amp;nbsp;parament_count_;&lt;/p&gt;&lt;p class="p0"&gt;4）普通函数命名：PascalCase。例如：&lt;span style="font-family: 'Times New Roman';"&gt;AddTableEntry()&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;5）存储函数：&lt;span style="font-family: 'Times New Roman';"&gt;linux&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;命名方法。例如：&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;　int&amp;nbsp;num_entries()&amp;nbsp;const&amp;nbsp;{return&amp;nbsp;num_entries_};&lt;/p&gt;&lt;p class="p0"&gt;　void&amp;nbsp;set_num_entries(){int&amp;nbsp;num_entries};&lt;/p&gt;&lt;p class="p0"&gt;6)枚举：值为全大写组成的单词，单词以_分割。例如MY_ENUM_VALUE&lt;/p&gt;&lt;p class="p0"&gt;7)类名、结构名：&lt;span style="font-family: 'Times New Roman';"&gt;PascalCase&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;　&lt;strong&gt;　二、函数参数&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;输入参数在钱，输出参数在后。&lt;/p&gt;&lt;p class="p0"&gt;　&lt;strong&gt;　三、头文件排序&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;C&lt;span style="font-family: 宋体;"&gt;系统头文件&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;C++&lt;span style="font-family: 宋体;"&gt;系统头文件&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;其他库头文件&lt;/p&gt;&lt;p class="p0"&gt;本项目内头文件&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;四、文件注释&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;1、创建时间&amp;nbsp;&amp;nbsp;作者&lt;/p&gt;&lt;p class="p0"&gt;2、修改时间&amp;nbsp;&amp;nbsp;修改人&amp;nbsp;&amp;nbsp;&amp;nbsp;修改函数列表&lt;/p&gt;&lt;p class="p0"&gt;3、头文件中，首先生命该类的作用，对函数的用法作简单说明&lt;/p&gt;&lt;p class="p0"&gt;&lt;strong&gt;五、其他约定&lt;/strong&gt;&lt;/p&gt;&lt;p class="p0"&gt;1&lt;span style="font-family: 宋体;"&gt;、每行不要超过&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;80&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个字符，包含长路径或者头文件保护的情况除外；&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;2&lt;span style="font-family: 宋体;"&gt;、设定编辑器将&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;tab&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;转换为空格，最好为&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;4&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;个空格；&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;3&lt;span style="font-family: 宋体;"&gt;、空循环体使用&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;{}&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;continue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，而不是一个分号；&lt;/span&gt;&lt;/p&gt;&lt;p class="p0"&gt;4&lt;span style="font-family: 宋体;"&gt;、不要使用匈牙利命名法。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;最重要的一点，和你所在的团队的编程风格保持一致，即使你团队的编程风格和上面所述冲突。&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangwei/aggbug/1826645.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangwei/archive/2010/09/15/1826645.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
