<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Think in G</title>
	<atom:link href="http://www.think-in-g.net/ghawk/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.think-in-g.net/ghawk/blog</link>
	<description>Never stop ThinkinG...</description>
	<lastBuildDate>Wed, 09 May 2012 23:48:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>2 Stories about Memory Leak in Objective-C</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/05/2-stories-about-memory-leak-in-objective-c/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/05/2-stories-about-memory-leak-in-objective-c/#comments</comments>
		<pubDate>Wed, 09 May 2012 16:45:43 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[memory management]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[trouble shooting]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=585</guid>
		<description><![CDATA[As we know, Objective-C uses reference counting as it&#8217;s memory management mechanism. It&#8217;s simple, reliable and efficient. But even the smart and powerful ARC, we still have to take care of each piece of code, or there might  be leaking somewhere, silently. Here, I will talk about two cases of memory leak. They are all [...]]]></description>
			<content:encoded><![CDATA[<p>As we know, Objective-C uses <strong>reference counting</strong> as it&#8217;s memory management mechanism. It&#8217;s simple, reliable and efficient. But even the smart and powerful ARC, we still have to take care of each piece of code, or there might  be leaking somewhere, <strong>silently</strong>.</p>
<p>Here, I will talk about two cases of memory leak. They are all from my recent project. Although a veteran might think these as nothing. But I still want to share the stories.</p>
<h2>Case 1: When Core Animation meets Delegate</h2>
<p>To create an awesome UI/UX, using animations is inevitable. Sometimes, I have to use <tt>CAAnimation</tt> directly instead of the convenient methods provided by the <tt>UIView</tt> class. And I usually use delegate objects to make these animation objects more controllable.</p>
<pre class="brush: objc; title: ; notranslate">
@implementation GHKLeakingController
// These codes cause memory leak due to a retain cycle.
- (void)showMask {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@&quot;opacity&quot;];
    animation.fromValue = [self.maskView.layer.presentationLayer valueForKeyPath:@&quot;opacity&quot;];
    animation.toValue = [NSNumber numberWithFloat:1.0f];
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeBoth;
    animation.duration = 1.0f;
    animation.delegate = self;

    [self.maskView.layer addAnimation:animation forKey:@&quot;fadeIn&quot;];
}

//The delegate method for the animation
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag) {
        NSLog(@&quot;%@&quot;, @&quot;The animation is finished. Do something here.&quot;);
    }
}
@end
</pre>
<p>When these code runs, everything looks OK. But, when you drop this instance of the controller, everything leaks! WHY?<span id="more-585"></span><br />
Let&#8217;s take a look at the object graph.</p>
<p style="text-align: center;"><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/05/leak-animation.jpg" rel="lightbox[585]"><img class="size-full wp-image-606 aligncenter" title="leak-animation" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/05/leak-animation.jpg" alt="" width="599" height="244" /></a></p>
<p>Pay attention to where marked <strong>(1)</strong> and <strong>(2)</strong>.</p>
<ol>
<li>Because I want the layer to remain it&#8217;s look after the animation stops. I use a common approach of overriding the default behavior of animation.
<pre class="brush: objc; title: ; notranslate">
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
</pre>
<p>By doing this, the layer will retain the animation until you remove it manually.</li>
<li>I also make the controller&#8217;s instance itself as the delegate object of the animation. As you can see in the object graph, since then, the controller is retained by the animation. Don&#8217;t be surprised! Apple has already <a title="CAAnimation Class Reference." href="http://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CAAnimation_class/Introduction/Introduction.html#//apple_ref/occ/instp/CAAnimation/delegate" target="_blank">documented this behavior</a>. Because this is a rare case of the delegate pattern, there even has a warning says:<br />
<blockquote><p>Important The delegate object is retained by the receiver. This is a rare exception to the memory management rules described in Advanced Memory Management Programming Guide.<br />
An instance of CAAnimation should not be set as a delegate of itself. Doing so (outside of a garbage-collected environment) will cause retain cycles.</p></blockquote>
</li>
</ol>
<p>Well, everything is clear now. I did both <strong>(1)</strong> and <strong>(2)</strong> at the same time, and didn&#8217;t realized that those objects had been connected as a big cycle. By manually removing the animation from the layer object in the delegate method, the cycle is broken.</p>
<pre class="brush: objc; highlight: [6]; title: ; notranslate">
//The delegate method for the animation
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag) {
        NSLog(@&quot;%@&quot;, @&quot;The animation is finished. Do something here.&quot;);
    }
    [self.mask.layer removeAnimationForKey:@&quot;fadeIn&quot;];
}
</pre>
<h2>Case 2: Gesture Recognizer &amp; Blocks</h2>
<p>In order to intercept the touch events sent to an instance of <tt>MKMapView</tt>. I googled and finally found a <a title="How to detect any tap inside an MKMapView (sans tricks)" href="http://stackoverflow.com/a/4064538/1078575" target="_blank">solution</a>. I created a customized gesture recognizer, in the <tt>-viewDidLoad</tt> method, I initialized a new instance of the recognizer and added it to the map view.</p>
<pre class="brush: objc; title: ; notranslate">
// WSTouchInterceptor.h

typedef void (^TouchesEventBlock)(UIGestureRecognizer * recognizer, NSSet * touches, UIEvent * event);

@interface WSTouchInterceptor : UIGestureRecognizer
@property (copy, nonatomic) TouchesEventBlock beginHandler;
@property (copy, nonatomic) TouchesEventBlock endHandler;
- (id)initWithTouchBeginHandler:(TouchesEventBlock)beginHandler touchEndHandler:(TouchesEventBlock)endHandler;
@end
</pre>
<p>&nbsp;</p>
<pre class="brush: objc; title: ; notranslate">
// WSTouchInterceptor.m

@implementation WSTouchInterceptor
@synthesize beginHandler = _beginHandler;
@synthesize endHandler = _endHandler;

- (id)initWithTouchBeginHandler:(TouchesEventBlock)beginHandler touchEndHandler:(TouchesEventBlock)endHandler {
    self = [super init];
    if (self) {
        self.beginHandler = beginHandler;
        self.endHandler = endHandler;
    }

    return self;
}
//...
@end
</pre>
<p>&nbsp;</p>
<pre class="brush: objc; title: ; notranslate">
@implementation GHKLeakingController
- (void)viewDidLoad
{
    [super viewDidLoad];

    //Initialize the event interceptor.
    UIGestureRecognizer *interceptor = nil;
    interceptor = [[WSTouchInterceptor alloc] initWithTouchBeginHandler:^(UIGestureRecognizer *recognizer, NSSet *touches, UIEvent *event) {
        [self handleTouchBegin];
    } touchEndHandler:^(UIGestureRecognizer *recognizer, NSSet *touches, UIEvent *event) {
        [self handleTouchEnd];
    }];
    [self.map addGestureRecognizer:interceptor];
}
@end
</pre>
<p>In the codes listed above. The event interceptor is initialized with two blocks. Each block references the &#8220;self&#8221; object. Of cause, the controller itself will be retained by the blocks. You already know what&#8217;s gonna happen, right? No?<br />
Again, let&#8217;s check the object graph. It is slightly simple than the previous one.</p>
<p style="text-align: center;"><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/05/leak-block-1.jpg" rel="lightbox[585]"><img class="aligncenter size-full wp-image-610" title="leak-block-1" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/05/leak-block-1.jpg" alt="" width="600" height="236" /></a></p>
<p>Yes! The blocks cause the problem. According to the Apple&#8217;s official <a title="Transitioning to ARC Release Notes" href="http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html" target="_blank">Transitioning to ARC Release Notes</a>, the better solution is to break the cycle by passing a weak reference into the block.</p>
<pre class="brush: objc; highlight: [9,11,13]; title: ; notranslate">
@implementation GHKLeakingController
- (void)viewDidLoad
{
    [super viewDidLoad];

    //Initialize the event interceptor.
    UIGestureRecognizer *interceptor = nil;

    GHKLeakingController * __weak handler = self;
    interceptor = [[WSTouchInterceptor alloc] initWithTouchBeginHandler:^(UIGestureRecognizer *recognizer, NSSet *touches, UIEvent *event) {
        [handler handleTouchBegin];
    } touchEndHandler:^(UIGestureRecognizer *recognizer, NSSet *touches, UIEvent *event) {
        [handler handleTouchEnd];
    }];
    [self.map addGestureRecognizer:interceptor];
}
@end
</pre>
<h2>Conclusion: What I&#8217;ve learned?</h2>
<p>In the above examples, there won&#8217;t be any problem if the animation is not added to the layer or the gesture recognizer is not added to the map view. I mean when writing codes, I usually take care of that the current object is owning what, but there has been less consideration about it is(or will be) owned by whom. When I add those objects to some parent objects, there&#8217;s more likely chance to make a retain cycle.<br />
When considering the ownership and the object graph, We have to look back as well as forward.</p>
<p>BTW: I found it&#8217;s really hard to find there is a retain cycle. If you have any suggestion about detecting the retain cycle, please tell me.</p>
<p>When I was writing this article, I found another article on this topic: <a href="http://www.cocoanetics.com/2012/03/block-retain-loop/" title="Block Retain Loop" target="_blank"><strong>Block Retain Loop</strong></a>. I think this is also worth reading.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/05/2-stories-about-memory-leak-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我对新iPad的感想</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/03/my-view-of-the-new-ipad/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/03/my-view-of-the-new-ipad/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 06:23:25 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[感想]]></category>
		<category><![CDATA[硬件]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[new iPad]]></category>
		<category><![CDATA[post pc]]></category>
		<category><![CDATA[trends]]></category>
		<category><![CDATA[趋势]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=560</guid>
		<description><![CDATA[当地时间三月七日上午，Apple如期推出了新一代iPad。和以往一样，Apple的设备总会成为人们热议的话题。 关于新设备的技术特性和细节，网上到处都是，我就不废话了。和以往的发布会一样，有人兴奋，也有人失望，不过失望好像比以往多了些。失望的人也许是因为觉得新iPad没有全新的外形、毫无悬念的Retina屏幕，所有的一切看起来只是iPad 2的一个小幅升级版本。 而我对这台设备的观点则比较积极。为什么这么说呢？主要有这么两点： 9.7&#8243;的Retina屏幕的意义 Apple为什么打造了这么大一个高分辨率屏幕呢？是为了让用户能够更好地看电影、修照片、看小说、玩游戏？我觉得这些事情只能代表这款屏幕所承载的意义的很小一部分，而其的真正意义在于：它能够还原生活中所有的平面视觉体验！有了这样一台设备，更多专业的需求也能得以满足。比如：工程师在iPad上查看图纸、医生用iPad阅读患者的透视影像等等，它完全可以代替传统的介质。这是新iPad的生命力的源泉！ 其实，从Apple针对iOS提出的 iOS Human Interface Guidelines 就能看出，苹果所追求的一直都是逼真的充满细节的视觉体验。我是个对乐器一窍不通的人，但当我看到GarageBand那逼真的界面时，禁不住会有上去摸一下试试的冲动。也许20年前有这个的话，多少我会去学点乐器的吧…… 正如新iPad广告中说的： Because when the screen becomes this good, it&#8217;s simply you and the things you care about. 对于应用开发商来说，尤其是游戏厂商，为了吸引客户以及展示自己的实力，他们会表现出对Retina屏幕更强的倾向。这也是为什么在发布会当天，第三方厂商代表还受邀上台发布了几款iPad独占游戏和应用。 对后PC时代定义的进一步深化 2010年，iPad首次亮相的时候，Apple说这是后PC时代的一个革命性产品。但当时有人却说iPad只是大号的iTouch。去年的WWDC大会上，Apple借用网上的言论回应了这种说法：把iPad比作是大号iTouch，就相当于把游泳池比作家里的浴缸。没错，从技术上来说，iPad的确是一个大号的iTouch，游泳池之于浴缸也一样，但是，在浴缸里你不能游泳，不是吗？正是这种无限的可能性，让Apple有了iPad的想法，而老乔也披露当初iPhone是从iPad的想法衍生出来的。一直以来iPhone/iTouch作为实现成本比较低的产品线，一直也在技术验证、市场反应等方面为iPad服务着，可想而知Apple是多么重视iPad这条产品线。 第一代iPad问世后的两年，许多消费点子产品厂商已经加入到了后PC时代的革命大潮中，纷纷推出自己的平板产品。而现在，Apple则又将这场革命推进了一大步。 究竟什么是后PC时代？后PC时代的特征是什么？ 后PC时代与web 2.0的盛行密不可分，随着web在人们生活中的比重越来越大，更多的人正在将web变成一种承载其生活方式的介质。人们通过网络分享、交流、工作、学习…… 在当今的web中，服务主要由内容和平台构成。而我认为在对web 2.0时代的理解上，Apple和其他厂商在理念上存在着根本的不同： 其他厂商为了推自家的产品而去做内容，但是Apple是为了给优质的内容提供一个出色的平台而去做产品。这个差异决定了市场定位，进而决定了其最终产品的不同。 （当然，我认为与Apple持同样观点的还有Amazon，正因为如此，他们的Kindle产品线才可能有现在这样的成就）。那么，在这样一个理念的指导下，Apple如何通过新的iPad来体现他们对这个时代的诠释呢？Apple的答案就是要你忘记产品本身，而专心去做你热衷的事情。这也是我们在iPad的广告中常常看到的场景。而在新iPad的宣传片开头，Apple就通过这么一段话进一步强调了这一点： We believe technology is at its very best when it&#8217;s invisible. When you&#8217;re​ conscious only [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/03/screen-shot-2012-03-08-at-4.20.28-am.png" rel="lightbox[560]"><img class="alignnone" style="border: none;" title="The new iPad" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/03/screen-shot-2012-03-08-at-4.20.28-am.png" alt="" width="80%" /></a></p>
<p>当地时间三月七日上午，Apple如期推出了新一代iPad。和以往一样，Apple的设备总会成为人们热议的话题。</p>
<p>关于新设备的技术特性和细节，网上到处都是，我就不废话了。和以往的发布会一样，有人兴奋，也有人失望，不过失望好像比以往多了些。失望的人也许是因为觉得新iPad没有全新的外形、毫无悬念的Retina屏幕，所有的一切看起来只是iPad 2的一个小幅升级版本。</p>
<p>而我对这台设备的观点则比较积极。为什么这么说呢？主要有这么两点：<span id="more-560"></span></p>
<h2>9.7&#8243;的Retina屏幕的意义</h2>
<p>Apple为什么打造了这么大一个高分辨率屏幕呢？是为了让用户能够更好地看电影、修照片、看小说、玩游戏？我觉得这些事情只能代表这款屏幕所承载的意义的很小一部分，而其的真正意义在于：<strong>它能够还原生活中所有的平面视觉体验</strong>！有了这样一台设备，更多专业的需求也能得以满足。比如：工程师在iPad上查看图纸、医生用iPad阅读患者的透视影像等等，它完全可以代替传统的介质。这是新iPad的生命力的源泉！</p>
<p>其实，从Apple针对iOS提出的 <a title="iOS Human Interface Guidelines" href="https://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html" target="_blank">iOS Human Interface Guidelines</a> 就能看出，苹果所追求的一直都是逼真的充满细节的视觉体验。我是个对乐器一窍不通的人，但当我看到GarageBand那逼真的界面时，禁不住会有上去摸一下试试的冲动。也许20年前有这个的话，多少我会去学点乐器的吧……</p>
<p>正如新iPad广告中说的：</p>
<blockquote><p><span style="font-size: medium;">Because when the screen becomes this good, it&#8217;s simply you and the things you care about.</span></p></blockquote>
<p>对于应用开发商来说，尤其是游戏厂商，为了吸引客户以及展示自己的实力，他们会表现出对Retina屏幕更强的倾向。这也是为什么在发布会当天，第三方厂商代表还受邀上台发布了几款iPad独占游戏和应用。</p>
<h2>对后PC时代定义的进一步深化</h2>
<p>2010年，iPad首次亮相的时候，Apple说这是后PC时代的一个革命性产品。但当时有人却说iPad只是大号的iTouch。去年的WWDC大会上，Apple借用网上的言论回应了这种说法：把iPad比作是大号iTouch，就相当于把游泳池比作家里的浴缸。没错，从技术上来说，iPad的确是一个大号的iTouch，游泳池之于浴缸也一样，但是，在浴缸里你不能游泳，不是吗？正是这种无限的可能性，让Apple有了iPad的想法，而老乔也披露当初iPhone是从iPad的想法衍生出来的。一直以来iPhone/iTouch作为实现成本比较低的产品线，一直也在技术验证、市场反应等方面为iPad服务着，可想而知Apple是多么重视iPad这条产品线。</p>
<p>第一代iPad问世后的两年，许多消费点子产品厂商已经加入到了后PC时代的革命大潮中，纷纷推出自己的平板产品。而现在，Apple则又将这场革命推进了一大步。</p>
<p>究竟什么是后PC时代？后PC时代的特征是什么？</p>
<p>后PC时代与web 2.0的盛行密不可分，随着web在人们生活中的比重越来越大，更多的人正在将web变成一种承载其生活方式的介质。人们通过网络分享、交流、工作、学习…… 在当今的web中，服务主要由内容和平台构成。而我认为在对web 2.0时代的理解上，Apple和其他厂商在理念上存在着根本的不同：</p>
<blockquote><p><span style="font-size: medium;">其他厂商为了推自家的产品而去做内容，但是Apple是为了给优质的内容提供一个出色的平台而去做产品。这个差异决定了市场定位，进而决定了其最终产品的不同。</span></p></blockquote>
<p>（当然，我认为与Apple持同样观点的还有Amazon，正因为如此，他们的Kindle产品线才可能有现在这样的成就）。那么，在这样一个理念的指导下，Apple如何通过新的iPad来体现他们对这个时代的诠释呢？Apple的答案就是要你忘记产品本身，而专心去做你热衷的事情。这也是我们在iPad的广告中常常看到的场景。而在新iPad的宣传片开头，Apple就通过这么一段话进一步强调了这一点：</p>
<blockquote><p><span style="font-size: medium;">We believe technology is at its very best when it&#8217;s invisible. When you&#8217;re​ conscious only of what you&#8217;re doing, not the device you&#8217;re doing it with. And the iPad is the perfect expression of our idea.</span></p></blockquote>
<p>是的，这才是技术带给人们的便利！让人们能够充分感受学习、生活中的快乐和美好，随时随地地与朋友分享他们的感受，每当看到这样的场景，不论是Apple，还是为此所努力的开发者们都会从心底里产生一种感动，进而激发出更优秀的创造力。所以，Apple并不是刻意地去创造一种产品，去改变人们的生活方式，而是积极地设法将科技与人们最自然的生活方式相融合，提供一种更好的体验。</p>
<h2>总结</h2>
<p>随着新的iPad发布，这标志着一种进步，同时也是一种回归，在PC发展了30年后的今天，PC正渐渐淡出生活回到专职的工作岗位上，而新一带的技术正在重新为我们找回那种自由自在的生活，这一切才刚开始。</p>
<p>当然，我也希望参与这场后PC时代运动的厂商们认真考虑一下，消费者究竟想要什么样的价值，你们究竟能为消费者提供什么样的价值。销量和营销额固然重要（对于Apple来说也是如此），但是，在这样一个时代里，想要取得好成绩，仅仅靠不断在硬件上推陈出新是不够的，硬件本身已经不是技术门槛了。</p>
<p>好了，感想就写到这里，真机到手后，再写写实际入手感言吧～</p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/03/my-view-of-the-new-ipad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>管理vim插件，你out了吗？</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/03/manage-vim-plugins-with-vundl/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/03/manage-vim-plugins-with-vundl/#comments</comments>
		<pubDate>Sat, 03 Mar 2012 13:34:32 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[系统安装配置]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[vundle]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=546</guid>
		<description><![CDATA[任何一款强大的编辑器都离不开数量庞大的插件支持。 刚迁移到Vim的时候，总是到vim.org上找插件自己下载安装。随着插件越来越多，.vim目录也越来越乱，也很难管理插件的版本。 去年的一次学习会上，同事告诉我最近比较流行的是通过git的sub module功能，来下载和安装插件，配合pathogen将插件以bundle的形式管理，这样也便于及时升级插件。可不幸的是，我的拖延症又犯了，迟迟没有采用该方法。 然而，事物的发展是不以人的意志而转移的，当我终于决定修改配置方案的时候，发现更便利的工具已经出现了！ 那就是Vundle！ vundle本身也是一个vim的插件，它提供了一组命令，让我们可以方便地搜索、安装、升级、卸载插件。 安装过程非常简单。 首先，将vundle安装到~/.vim/bundle/vundle目录下。 然后，编辑.vimrc，从官方文档上将vundle的配置粘贴进去。 再在配置中加入自己所需的插件（上面配置中的高亮部分）就可以了。具体插件的格式有几种，官方的范例有详细介绍，这里就不啰嗦了。 保存后，启动vim，在命令行中输入BundleInstall，回车后，Vundle就会自动根据配置逐一安装插件了（整个过程有视觉反馈，体验非常好），安装过程如下图： 安装完成后，重新载入一次.vimrc，一切就OK了。如果需要升级插件则使用BundleInstall!命令即可，删除则使用BundleClean，非常直白。 现在，整个世界清爽多了，配置新环境的时候，只要带上我的vimrc，再联上git，就能让vim变成我熟悉的样子了～ （还为我省下了些git的空间）]]></description>
			<content:encoded><![CDATA[<p>任何一款强大的编辑器都离不开数量庞大的插件支持。</p>
<p>刚迁移到Vim的时候，总是到vim.org上找插件自己下载安装。随着插件越来越多，.vim目录也越来越乱，也很难管理插件的版本。</p>
<p>去年的一次学习会上，同事告诉我最近比较流行的是通过git的sub module功能，来下载和安装插件，配合pathogen将插件以bundle的形式管理，这样也便于及时升级插件。可不幸的是，我的拖延症又犯了，迟迟没有采用该方法。</p>
<p>然而，事物的发展是不以人的意志而转移的，当我终于决定修改配置方案的时候，发现更便利的工具已经出现了！</p>
<p>那就是<strong><a href="https://github.com/gmarik/vundle" target="_blank">Vundle</a></strong>！<span id="more-546"></span></p>
<p>vundle本身也是一个vim的插件，它提供了一组命令，让我们可以方便地搜索、安装、升级、卸载插件。</p>
<p>安装过程非常简单。</p>
<p>首先，将vundle安装到~/.vim/bundle/vundle目录下。</p>
<p>然后，编辑.vimrc，从官方文档上将vundle的配置粘贴进去。</p>
<pre class="brush: plain; highlight: [25,26,27,28,29,30,31,32,33,34,35]; title: ; notranslate">set nocompatible               &quot; be iMproved
filetype off                   &quot; required!

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

&quot; let Vundle manage Vundle
&quot; required!
Bundle 'gmarik/vundle'

&quot; My Bundles here:
&quot;
&quot; original repos on github
&quot; Bundle 'tpope/vim-fugitive'
&quot; Bundle 'Lokaltog/vim-easymotion'
&quot; Bundle 'rstacruz/sparkup', {'rtp': 'vim/'}
&quot; Bundle 'tpope/vim-rails.git'
&quot; vim-scripts repos
&quot; Bundle 'L9'
&quot; Bundle 'FuzzyFinder'
&quot; non github repos
&quot; Bundle 'git://git.wincent.com/command-t.git'
&quot; ...

Bundle 'molokai'
Bundle 'genutils'
Bundle 'The-NERD-tree'
Bundle 'bufexplorer.zip'
Bundle 'lookupfile'
Bundle 'snipMate'
Bundle 'snipmate-snippets'
Bundle 'taglist-plus'
Bundle 'fugitive.vim'
Bundle 'jslint.vim'
Bundle 'ZenCoding.vim'

filetype plugin indent on     &quot; required!
&quot;
&quot; Brief help
&quot; :BundleList          - list configured bundles
&quot; :BundleInstall(!)    - install(update) bundles
&quot; :BundleSearch(!) foo - search(or refresh cache first) for foo
&quot; :BundleClean(!)      - confirm(or auto-approve) removal of unused bundles
&quot;
&quot; see :h vundle for more details or wiki for FAQ
&quot; NOTE: comments after Bundle command are not allowed..
</pre>
<p>再在配置中加入自己所需的插件（上面配置中的高亮部分）就可以了。具体插件的格式有几种，官方的范例有详细介绍，这里就不啰嗦了。<br />
保存后，启动vim，在命令行中输入BundleInstall，回车后，Vundle就会自动根据配置逐一安装插件了（整个过程有视觉反馈，体验非常好），安装过程如下图：</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/03/BundleInstall.jpg" rel="lightbox[546]"><img class="alignnone size-full wp-image-552" title="BundleInstall" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/03/BundleInstall.jpg" alt="" width="90%" /></a></p>
<p>安装完成后，重新载入一次.vimrc，一切就OK了。如果需要升级插件则使用BundleInstall!命令即可，删除则使用BundleClean，非常直白。</p>
<p>现在，整个世界清爽多了，配置新环境的时候，只要带上我的vimrc，再联上git，就能让vim变成我熟悉的样子了～ （还为我省下了些git的空间）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/03/manage-vim-plugins-with-vundl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用Key-Value Observing解耦视图控制器</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/02/decoupling-view-controllers-with-key-value-observing/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/02/decoupling-view-controllers-with-key-value-observing/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 11:34:11 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Key-Value Coding]]></category>
		<category><![CDATA[Key-Value Observing]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=522</guid>
		<description><![CDATA[在Objective-C中，有一种称为Key-Value Coding（KVC）的机制。简单地讲，就是一组为对象属性命名的规则。符合这个规则的对象，可以使用runtime提供的-valueForKeyPath:和-setValueForKeyPath:方法进行访问。类似Java中的JavaBean属性。在一个对象图中，只需要用字符串指定一个属性的路径名称即可。比如： 只要对象支持KVC，不仅能够更方便地动态存取属性，而且还能使用runtime所提供的另一个强力机制：Key-Value Observing（KVO）。 熟悉Java的同学一定知道java.util.Observer/java.util.Observable这组接口，这是Java中观察者模式的基础设施。而在Objective-C中，NSObject类有一个名为NSKeyValueObserverRegistration的category，其中申明了注册和取消观察者的方法，这也就意味着对于所有符合KVC规则的NSObject子类，其对象都能成为被观察对象。 在Java中，类库对观察者模式的支持仅仅是接口级别的。而在Objective-C中，监听和通知可以到达属性级别，也就是KeyPath。Apple的官方文档记载了详细的用法，这里就不废话了。 这里主要想说一说通过KVO机制，实现视图控制器的解藕。 首先，看一个例子： 这是一个很典型的iOS应用画面。一个UIViewController驱动一个UITableView。该控制器同时也负责读取新的数据，当从服务端取得新的数据时，刷新自身管理的列表视图，并更新tabbar上的badge。 最直观最简单的实现，其原理是这样的： 这种实现的代码大概是这个样子的： 对于复杂的系统来说，这样做会有以下几个问题： 主控制器由于需要协调其他多个视图或控制器，其功能会变得很复杂。 主控制器需要管理数据容器以及其他控制器的生命周期，对应用逻辑来说，这是一种噪音。 在GUI应用中，因为UI部分的对象图有时会变得非常复杂，复杂的耦合关系会让整个系统变得非常难以维护和测试。 为了解决上述问题，我们可以导入一个中间对象，分担这些协调工作，也就是GoF模式中的Mediator模式，在OS X/iOS应用中，这样的中间对象通常可由AppDelegate来担当。 但其实，通过KVO机制，我们可以利用runtime更优雅地解决这个问题。 原理如下图所示： 首先，将数据容器剥离到控制器以外。其次，将各个控制器之间的依赖关系切断，在控制器初始化后，通过KVO机制注册成为数据源的观察者。而数据源只需要完成自己的更新任务，当属性发生变化后，runtime会自动通知其观察者。这样，各个对象就无须关心对方的生命周期，能大大减少逻辑上的杂音。 简单写点代码示例： 基本上就是这样，只要对代码稍作改动，就能充分利用KVO实现视图控制器的解藕。而且，KVO的功能很强大，比如能在通知时提供属性变更前后的信息等等，好好利用可以节省不少代码。 参考：Key-Value Observing Programming Guide]]></description>
			<content:encoded><![CDATA[<p>在Objective-C中，有一种称为<a title="Key-Value Coding Compliance" href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/Compliant.html#//apple_ref/doc/uid/20002172ple_ref/doc/uid/20002172" target="_blank">Key-Value Coding（KVC）</a>的机制。简单地讲，就是一组为对象属性命名的规则。符合这个规则的对象，可以使用runtime提供的<tt>-valueForKeyPath:</tt>和<tt>-setValueForKeyPath:</tt>方法进行访问。类似Java中的JavaBean属性。在一个对象图中，只需要用字符串指定一个属性的路径名称即可。比如：</p>
<pre class="brush: objc; title: ; notranslate"> id foo = [bar valueForKeyPath:@&quot;frame.origin.x&quot;];</pre>
<p>只要对象支持KVC，不仅能够更方便地动态存取属性，而且还能使用runtime所提供的另一个强力机制：<strong>Key-Value Observing（KVO）</strong>。</p>
<p>熟悉Java的同学一定知道<tt>java.util.Observer/java.util.Observable</tt>这组接口，这是Java中观察者模式的基础设施。而在Objective-C中，<tt>NSObject</tt>类有一个名为<tt>NSKeyValueObserverRegistration</tt>的category，其中申明了注册和取消观察者的方法，这也就意味着对于所有符合KVC规则的NSObject子类，其对象都能成为被观察对象。</p>
<p>在Java中，类库对观察者模式的支持仅仅是接口级别的。而在Objective-C中，监听和通知可以到达属性级别，也就是KeyPath。Apple的官方文档记载了详细的用法，这里就不废话了。</p>
<p>这里主要想说一说通过KVO机制，实现视图控制器的解藕。</p>
<p>首先，看一个例子：</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/sample-view.png" rel="lightbox[522]"><img class="alignnone size-full wp-image-530" title="Sample view" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/sample-view.png" alt="" width="271" height="230" /></a></p>
<p><span id="more-522"></span>这是一个很典型的iOS应用画面。一个UIViewController驱动一个UITableView。该控制器同时也负责读取新的数据，当从服务端取得新的数据时，刷新自身管理的列表视图，并更新tabbar上的badge。</p>
<p>最直观最简单的实现，其原理是这样的：</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/simple-implementation.png" rel="lightbox[522]"><img class="alignnone  wp-image-532" title="A simple implementation" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/simple-implementation.png" alt="" /></a></p>
<p>这种实现的代码大概是这个样子的：</p>
<pre class="brush: objc; title: ; notranslate">
@implementation MyViewController
- (void)fetchUpdates {
    [self fetchDataWithCompletionBlock:^{
        [self refreshListView];
        [self displayBadgeOnTabbar];
    }]
}
//...
@end
</pre>
<p>对于复杂的系统来说，这样做会有以下几个问题：</p>
<ul>
<li>主控制器由于需要协调其他多个视图或控制器，其功能会变得很复杂。</li>
<li>主控制器需要管理数据容器以及其他控制器的生命周期，对应用逻辑来说，这是一种噪音。</li>
<li>在GUI应用中，因为UI部分的对象图有时会变得非常复杂，复杂的耦合关系会让整个系统变得非常难以维护和测试。</li>
</ul>
<p>为了解决上述问题，我们可以导入一个中间对象，分担这些协调工作，也就是<a href="http://en.wikipedia.org/wiki/Mediator_pattern" target="_blank">GoF模式中的Mediator模式</a>，在OS X/iOS应用中，这样的中间对象通常可由AppDelegate来担当。</p>
<p>但其实，通过KVO机制，我们可以利用runtime更优雅地解决这个问题。</p>
<p>原理如下图所示：</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/kvo-implementation-1.png" rel="lightbox[522]"><img class="alignnone size-full wp-image-539" title="Implementation with KVO" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/02/kvo-implementation-1.png" alt="" width="655" height="326" /></a></p>
<p>首先，将数据容器剥离到控制器以外。其次，将各个控制器之间的依赖关系切断，在控制器初始化后，通过KVO机制注册成为数据源的观察者。而数据源只需要完成自己的更新任务，当属性发生变化后，runtime会自动通知其观察者。这样，各个对象就无须关心对方的生命周期，能大大减少逻辑上的杂音。</p>
<p>简单写点代码示例：</p>
<pre class="brush: objc; title: ; notranslate">
@implementation MyViewController
- (void)viewDidLoad {
    //初始化时注册成为观察者
    id dataSource = [MyDataSource sharedInstance];
    [dataSource addObserver:self forKeyPath:@&quot;newItems&quot; options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)fetchUpdates {
    [[MyDataSource sharedInstance] fetchData];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    // 取得新数据后更新table view。
    if ([keyPath isEqualToString:@&quot;newItems&quot;]) {
        [self refreshListView];
    }
}
//...
@end

@implementation MyTabbarController
- (void)viewDidLoad {
    //初始化时注册成为观察者
    id dataSource = [MyDataSource sharedInstance];
    [dataSource addObserver:self forKeyPath:@&quot;newItems&quot; options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    // 取得新数据后更新 badge。
    if ([keyPath isEqualToString:@&quot;newItems&quot;]) {
        [self displayBadgeOnTabbar];
    }
}
//...
@end
</pre>
<p>基本上就是这样，只要对代码稍作改动，就能充分利用KVO实现视图控制器的解藕。而且，KVO的功能很强大，比如能在通知时提供属性变更前后的信息等等，好好利用可以节省不少代码。</p>
<p>参考：<a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177i" target="_blank">Key-Value Observing Programming Guide</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/02/decoupling-view-controllers-with-key-value-observing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>逻辑、直觉、iBooks Author</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/01/logic-intuition-and-ibooks-author/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/01/logic-intuition-and-ibooks-author/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 05:47:27 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[翻译]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iBooks]]></category>
		<category><![CDATA[iBooks Author]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[publishing]]></category>
		<category><![CDATA[reading experience]]></category>
		<category><![CDATA[textbook]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=515</guid>
		<description><![CDATA[原文链接：論理と直感とiBooks Author 译文 说起“逻辑”和“直觉”，人们通常认为这是两个相互对立的概念。关于这两者，可以讨论的方面有许多，在这篇博客中，我想就文书的格式和版式展开些讨论。 从文脉的技术角度来说，所有的文章其构造都应该具有逻辑性。计算机很喜欢这种逻辑结构鲜明的文章。具体说来，写文章的时候，先有标题，对吧？然后是章，每章也有自己的标题，而章又由节构成，节也有标题，其次才是正文…… 作者就是根据这样树状的逻辑结构将文章一点一点堆砌起来的。这样写文章，诸如抽出文章的大纲、简便地生成目录、明确检索目标这样的任务都会变得很方便。这是对于计算机而言的。 那么，文章要给别人看的时候呢？这就需要直觉上的版式了。在页面上布置标题的位置、设计页眉、正文分成四栏、给需要强调的内容配上插图…… 安排各种有助于阅读的要素。这些设计是为读者服务的。在这个过程中，会破坏文章的逻辑结构。心中想着文章的逻辑结构，默念“啊！绝对不能破坏逻辑结构！”，同时，直觉却告诉自己“这样改不是更有助于理解吗？” 于是，逻辑和直觉形成了一种对立。 现在的Web就是这样一个逻辑和直觉互不相容的常见例子。HTML是用于表述文章逻辑结构的格式，但尽管如此，为了实现复杂的版式，人们将各种排版技巧发挥到了极致。当前的Web是充满了各种碎片信息的集合，很难将这些碎片还原成原有的语义信息。 再来看看iBooks Author。iBooks Author的魅力在于能通过直觉化的方式方便地进行排版。使用拖拽的方式就能为文章配上插图，对于任何人来说，上手都很容易。而且，做出的书相当具有表现力。通常，引入这类功能的同时，文章的逻辑结构就会变得支离破碎。最早看到iBooks Author的演示时，我心里想的是：哎呀！这样岂不是把课本的逻辑结构完全给破坏了吗！ 亲自体验过后，我还是发现了课本中的逻辑结构。最粗的结构是：书 →章→节。再细分下去，通过指定段落的样式，又可以为其增加次级的逻辑结构。插图和图表看似可以自由安排，但实际上是跟段落关联在一起的。从体裁分类上讲，就是从属于某个段落的插图。 其次，将iPad转为纵向时，这种iBooks Author做的易于阅读的版式就会发生变化。旋转至纵向后，插图就会出现在左侧的边栏中，完全从正文中独立出来。也就是说，横向布局的版式是直觉式的阅读模式，而纵向布局的版式则是展现课本逻辑结构的俯瞰模式。这种让两种对立的结构共存的方式是我之前完全没有想到的。真叫人佩服。 让阅读体验“在逻辑和直觉的狭缝间游刃有余（Between Logic and Intuition）”。这是真正激动人心的本质所在。我希望使用这些电子课本的学生朋友们也能体会到这一点。 看了本文后的感想 我想到了数年前，曾尝试过使用LaTeX排版，写文章。因为很多用过的人说，LaTeX系统很强调文章的逻辑结构。只要逻辑结构正确，排版引擎会自动完成许多工作，产生漂亮的版式。可我既不是数学系学生那种重度LaTeX使用者，也没有花时间去记去练习。要掌握LaTeX实在有点力不从心，最终还是放弃了。 另外，iBooks Author不同于MS Word/Pages这种泛用的排版工具，它是一款专用工具，其出版的目标媒体仅限于iPad。虽然这一点遭到不少指责和批评，但站在作者和读者的立场上，我觉得就目前而言，这种限制对于良好的阅读体验来说是很必要的。 我还是耐心等待iPad 3吧！]]></description>
			<content:encoded><![CDATA[<p>原文链接：<a title="論理と直感とiBooks Author" href="http://hmdt.jp/blog/?p=417" target="_blank">論理と直感とiBooks Author</a></p>
<h2>译文</h2>
<p>说起“逻辑”和“直觉”，人们通常认为这是两个相互对立的概念。关于这两者，可以讨论的方面有许多，在这篇博客中，我想就文书的格式和版式展开些讨论。</p>
<p>从文脉的技术角度来说，所有的文章其构造都应该具有逻辑性。计算机很喜欢这种逻辑结构鲜明的文章。具体说来，写文章的时候，先有标题，对吧？然后是章，每章也有自己的标题，而章又由节构成，节也有标题，其次才是正文…… 作者就是根据这样树状的逻辑结构将文章一点一点堆砌起来的。这样写文章，诸如抽出文章的大纲、简便地生成目录、明确检索目标这样的任务都会变得很方便。这是对于计算机而言的。</p>
<p>那么，文章要给别人看的时候呢？这就需要直觉上的版式了。在页面上布置标题的位置、设计页眉、正文分成四栏、给需要强调的内容配上插图…… 安排各种有助于阅读的要素。这些设计是为读者服务的。在这个过程中，会破坏文章的逻辑结构。心中想着文章的逻辑结构，默念“啊！绝对不能破坏逻辑结构！”，同时，直觉却告诉自己“这样改不是更有助于理解吗？” 于是，逻辑和直觉形成了一种对立。<span id="more-515"></span></p>
<p>现在的Web就是这样一个逻辑和直觉互不相容的常见例子。HTML是用于表述文章逻辑结构的格式，但尽管如此，为了实现复杂的版式，人们将各种排版技巧发挥到了极致。当前的Web是充满了各种碎片信息的集合，很难将这些碎片还原成原有的语义信息。</p>
<p>再来看看iBooks Author。iBooks Author的魅力在于能通过直觉化的方式方便地进行排版。使用拖拽的方式就能为文章配上插图，对于任何人来说，上手都很容易。而且，做出的书相当具有表现力。通常，引入这类功能的同时，文章的逻辑结构就会变得支离破碎。最早看到iBooks Author的演示时，我心里想的是：哎呀！这样岂不是把课本的逻辑结构完全给破坏了吗！<br />
<img id="" title="" src="http://hmdt.jp/blog/wp-content/uploads/2012/01/ibooks_landscape.png" alt="" /></p>
<p>亲自体验过后，我还是发现了课本中的逻辑结构。最粗的结构是：书 →章→节。再细分下去，通过指定段落的样式，又可以为其增加次级的逻辑结构。插图和图表看似可以自由安排，但实际上是跟段落关联在一起的。从体裁分类上讲，就是从属于某个段落的插图。</p>
<p>其次，将iPad转为纵向时，这种iBooks Author做的易于阅读的版式就会发生变化。旋转至纵向后，插图就会出现在左侧的边栏中，完全从正文中独立出来。也就是说，横向布局的版式是直觉式的阅读模式，而纵向布局的版式则是展现课本逻辑结构的俯瞰模式。这种让两种对立的结构共存的方式是我之前完全没有想到的。真叫人佩服。<br />
<img id="" title="" src="http://hmdt.jp/blog/wp-content/uploads/2012/01/ibooks_portrait.png" alt="" /></p>
<p>让阅读体验“在逻辑和直觉的狭缝间游刃有余（Between Logic and Intuition）”。这是真正激动人心的本质所在。我希望使用这些电子课本的学生朋友们也能体会到这一点。</p>
<h2>看了本文后的感想</h2>
<p>我想到了数年前，曾尝试过使用LaTeX排版，写文章。因为很多用过的人说，LaTeX系统很强调文章的逻辑结构。只要逻辑结构正确，排版引擎会自动完成许多工作，产生漂亮的版式。可我既不是数学系学生那种重度LaTeX使用者，也没有花时间去记去练习。要掌握LaTeX实在有点力不从心，最终还是放弃了。</p>
<p>另外，iBooks Author不同于MS Word/Pages这种泛用的排版工具，它是一款专用工具，其出版的目标媒体仅限于iPad。虽然这一点遭到不少指责和批评，但站在作者和读者的立场上，我觉得就目前而言，这种限制对于良好的阅读体验来说是很必要的。</p>
<p>我还是耐心等待iPad 3吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/01/logic-intuition-and-ibooks-author/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于Core Animation工具箱的构想</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/01/a-plan-ofcore-animation-tookit/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/01/a-plan-ofcore-animation-tookit/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 11:55:18 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=502</guid>
		<description><![CDATA[最近在构思一个用于Mac/iOS开发的工具。感觉比较庞大，脑子里的东西比较混乱，决定先把最初的设想写下来，然后再一步步细化。 问题的由来 这个构思的起因是2011年底前的一个iOS项目。设计MM为了吸引用户，在UI中设计了各种可爱的元素。也差不多在这同时，Path 2登场了。其精致的动画让设计MM意识到动画也是体现UI表现力的重要手段。于是，她就开始设计中增加动画元素。 围绕这这些动画效果，我发现在设计和开发过程中有不少问题： UI设计师如何描述动画 动画与传统的静态UI不同，单单凭借静态的设计是很难把问题说清楚的。如果采用关键帧的方式去绘制一些分镜头的脚本，会给设计师增加不少工作压力。 开发人员如何实现动画 在Mac/iOS平台上，实现动画主要靠的是Core Animation框架。然而Core Animation比较底层，因此Apple对其进行了封装，提供了Cocoa Animation以方便开发人员实现动画。但不论在Mac还是iOS上，通过编程方式实现动画效果依然需要大量的代码，而且对于比较复杂的动画，开发人员还是需要直接通过Core Animation操纵CALayer、CAAnimation来实现。在我的项目中，最重的view controller里，居然有80%的代码用于实现动画效果。 于是我意识到，这样的开发是有问题的。理由很简单，设计师所设计的是动画，既然是动画，就不应该是几个分镜，几个关键帧这样的半成品。更不应该等到开发人员将代码写出来，再就具体的效果进行讨论。而开发人员也不应该堆砌大量的代码用于动画，因为同时具有艺术感和代码实现能力的开发人员真的非常少。想要做出高质量的动画，这样的过程没有几个回合是搞不定的。总之一句话： Does real animator write codes? Definitely NOT! 在设计师和开发人员之间必须有个工具扮演桥梁的角色。类似于Flash上的工作流，设计师能够通过该工具直接做出大部分动画效果，而开发人员则在项目中导入这些预先定义好的动画脚本，并根据需要进行一些优化和微调。 如果存在这样的工具，不仅能有效简化设计师和程序员之间的沟通过程，实现工作职责的更合理分配。更重要的是，它还能使代码变得干净，提升代码和动画的可复用性。 方案构想 以我目前对Cocoa/Cocoa Touch的理解，这个工具应该包括以下几个部分 一种用于描述动画以及相关project的数据格式 暂时并没有夸平台的想法，所以初步考虑采用Cocoa的Archiving机制实现。 一套用于Cocoa/Cocoa Touch的框架 该框架用于将保存在文件中的动画脚本还原为代码，并通过回调等形式与应用代码进行数据绑定。最后通过Core Animation框架执行动画。 一个用于设计动画的桌面应用 该应用的目标是让设计人员能够直观地设计动画，并能够保存读取1所提到的数据格式。具体的功能可能包括： 一个静态编辑器，用于编辑CALayer及其子类的实例（设置背景、透明度、阴影、过滤器等）。 一个动画编辑器，用于生成简单动画或是复杂的关键帧动画、AnimationGroup等对象。 辅助对象编辑器，用于编辑动画图层的约束关系、MediaTimingFunction等辅助对象。 …… （余下的仍在设想） 目前的状况 这个构想是去年末渐渐浮现出来的。于是最近开始系统地围绕着Core Animation相关技术以以及Mac桌面应用的开发开始调查和学习。目前的感觉是与iOS相比，Mac OS X的技术平台要复杂得多。为了了解Core Animation的来龙去脉，连2006/2007年苹果的Mac技术讲座都翻出来了，由于苹果在技术架构上秉承实用主义的原则，在这几年的时间里，整个技术体系的更新非常快（当时还有不少视频讲如何使用GC的……） 因此，技术准备的时间会比较长，在把相关的问题理清楚之前，不打算贸然开始开发工作。 鉴于最近看了不少Core Animation的资料，我也打算将这些资料整理成博客陆续放出。]]></description>
			<content:encoded><![CDATA[<p>最近在构思一个用于Mac/iOS开发的工具。感觉比较庞大，脑子里的东西比较混乱，决定先把最初的设想写下来，然后再一步步细化。</p>
<h2>问题的由来</h2>
<p>这个构思的起因是2011年底前的一个iOS项目。设计MM为了吸引用户，在UI中设计了各种可爱的元素。也差不多在这同时，Path 2登场了。其精致的动画让设计MM意识到动画也是体现UI表现力的重要手段。于是，她就开始设计中增加动画元素。</p>
<p>围绕这这些动画效果，我发现在设计和开发过程中有不少问题：</p>
<ul>
<li>UI设计师如何描述动画<br />
动画与传统的静态UI不同，单单凭借静态的设计是很难把问题说清楚的。如果采用关键帧的方式去绘制一些分镜头的脚本，会给设计师增加不少工作压力。</li>
<li>开发人员如何实现动画<br />
在Mac/iOS平台上，实现动画主要靠的是Core Animation框架。然而Core Animation比较底层，因此Apple对其进行了封装，提供了Cocoa Animation以方便开发人员实现动画。但不论在Mac还是iOS上，通过编程方式实现动画效果依然需要大量的代码，而且对于比较复杂的动画，开发人员还是需要直接通过Core Animation操纵CALayer、CAAnimation来实现。在我的项目中，最重的view controller里，居然有80%的代码用于实现动画效果。</li>
</ul>
<p>于是我意识到，这样的开发是有问题的。理由很简单，设计师所设计的是动画，既然是动画，就不应该是几个分镜，几个关键帧这样的半成品。更不应该等到开发人员将代码写出来，再就具体的效果进行讨论。而开发人员也不应该堆砌大量的代码用于动画，因为同时具有艺术感和代码实现能力的开发人员真的非常少。想要做出高质量的动画，这样的过程没有几个回合是搞不定的。总之一句话：</p>
<blockquote><p><em><span style="font-size: large;">Does real animator write codes? Definitely NOT!</span></em></p></blockquote>
<p>在设计师和开发人员之间必须有个工具扮演桥梁的角色。类似于Flash上的工作流，设计师能够通过该工具直接做出大部分动画效果，而开发人员则在项目中导入这些预先定义好的动画脚本，并根据需要进行一些优化和微调。</p>
<p>如果存在这样的工具，不仅能有效简化设计师和程序员之间的沟通过程，实现工作职责的更合理分配。更重要的是，它还能使代码变得干净，提升代码和动画的可复用性。<span id="more-502"></span></p>
<h2>方案构想</h2>
<p>以我目前对Cocoa/Cocoa Touch的理解，这个工具应该包括以下几个部分</p>
<ol>
<li>一种用于描述动画以及相关project的数据格式<br />
暂时并没有夸平台的想法，所以初步考虑采用Cocoa的Archiving机制实现。</li>
<li>一套用于Cocoa/Cocoa Touch的框架<br />
该框架用于将保存在文件中的动画脚本还原为代码，并通过回调等形式与应用代码进行数据绑定。最后通过Core Animation框架执行动画。</li>
<li>一个用于设计动画的桌面应用<br />
该应用的目标是让设计人员能够直观地设计动画，并能够保存读取1所提到的数据格式。具体的功能可能包括：</p>
<ul>
<li>一个静态编辑器，用于编辑CALayer及其子类的实例（设置背景、透明度、阴影、过滤器等）。</li>
<li>一个动画编辑器，用于生成简单动画或是复杂的关键帧动画、AnimationGroup等对象。</li>
<li>辅助对象编辑器，用于编辑动画图层的约束关系、MediaTimingFunction等辅助对象。</li>
<li>…… （余下的仍在设想）</li>
</ul>
</li>
</ol>
<h2>目前的状况</h2>
<p>这个构想是去年末渐渐浮现出来的。于是最近开始系统地围绕着Core Animation相关技术以以及Mac桌面应用的开发开始调查和学习。目前的感觉是与iOS相比，Mac OS X的技术平台要复杂得多。为了了解Core Animation的来龙去脉，连2006/2007年苹果的Mac技术讲座都翻出来了，由于苹果在技术架构上秉承实用主义的原则，在这几年的时间里，整个技术体系的更新非常快（当时还有不少视频讲如何使用GC的……） 因此，技术准备的时间会比较长，在把相关的问题理清楚之前，不打算贸然开始开发工作。</p>
<p>鉴于最近看了不少Core Animation的资料，我也打算将这些资料整理成博客陆续放出。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/01/a-plan-ofcore-animation-tookit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>新年逛书店</title>
		<link>http://www.think-in-g.net/ghawk/blog/2012/01/new-year-book-hunting/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2012/01/new-year-book-hunting/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 07:05:38 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[书籍]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[computer]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=462</guid>
		<description><![CDATA[因为最近想尝试一些OpenGL ES的开发，所以想找本入门+进阶的书。在amazon上找到几本，但仅凭preview和review没有办法确定这些书是否适合我，于是去书店逛了逛。 到了书店的计算机部，有好多书吸引了我，有的是因为主题，有的则是因为别致的设计。 令人震撼的骨董计算机之美 摄影和计算机让人联想起什么？如果你想到的只是PS，那么你绝对应该看看O&#8217;Reilly的这本 Core Memory : a visual survey of vintage computers （目前还没有中文版，我称之为《Core Memory：骨董计算机之美》），这是摄影艺术对于计算机之美的诠释、对于机器和人类智慧之美的诠释！ 我从time.com上找来了一些书中的图片，在这里引用两幅。 这本书是2007年出版的，这么久了，在国内却一直不知道…… 游戏书 日本在游戏市场和游戏开发领域都在世界的前列。游戏方面自然也有不少书（当然不是指游戏攻略……）。 最注目的是这本 《死ぬまでにやりたいゲーム1001》（到死也想玩的1001款游戏），看封面就知道这是本纵贯游戏史的作品了。960页的容量，让其成为名副其实的砖头。看着这些亲切的画面，确实能引起70、80年代的人很强烈的共鸣。这些游戏不仅在当时是划时代的创新，也为后来整个游戏行业的发展奠定了基础。 另外一个书架上有许多游戏开发的书，主要都是与游戏相关的数学、物理、AI方面的书。其中有一本叫《弾幕 最強のシューティングゲームを作る！》（弹幕 制作最强的射击游戏）吸引了我。翻开一看，其实都是些公式和程序，顾名思义，就是教你怎么设计弹幕的。以前只知道很多射击游戏的弹幕很变态，原来弹幕的设计也有这么多学问…… 那些骨灰级玩家是不是都研究过弹幕的算法的呀？ 开发人员工作方法 有几本关于工作方法的书不错，不过鉴于时间原因，没有细看。 1.《リファクタリング・ウェットウェア ―達人プログラマーの思考法と学習法》 中文版《程序员的思维修炼》 原版      Pragmatic Thinking and Learning: Refactor Your Wetware 2. 《ゲームストーミング ―会議、チーム、プロジェクトを成功へと導く87のゲーム》 Game Storming: A Playbook for Innovators, Rulebreakers, and Changemakers 3. 《エンジニアとして生き方》(IT工程师的生活方式)]]></description>
			<content:encoded><![CDATA[<p>因为最近想尝试一些OpenGL ES的开发，所以想找本入门+进阶的书。在amazon上找到几本，但仅凭preview和review没有办法确定这些书是否适合我，于是去书店逛了逛。</p>
<p>到了书店的计算机部，有好多书吸引了我，有的是因为主题，有的则是因为别致的设计。</p>
<h2>令人震撼的骨董计算机之美</h2>
<p>摄影和计算机让人联想起什么？如果你想到的只是PS，那么你绝对应该看看O&#8217;Reilly的这本 <a href="http://www.amazon.com/Core-Memory-Visual-Vintage-Computers/dp/0811854426/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1325601152&amp;sr=1-1" target="_blank">Core Memory : a visual survey of vintage computers</a> （目前还没有中文版，我称之为《Core Memory：骨董计算机之美》），这是摄影艺术对于计算机之美的诠释、对于机器和人类智慧之美的诠释！</p>
<p><a href="http://www.time.com/time/photogallery/0,29307,1670168,00.html" target="_blank">我从time.com上找来了一些书中的图片</a>，在这里引用两幅。</p>
<div id="attachment_463" class="wp-caption alignleft" style="width: 310px"><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/vintage_computers_02.jpg" target="_blank" rel="lightbox[462]"><img class="wp-image-463 " style="border: 0pt none;" title="Eniac的电子管阵列" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/vintage_computers_02-300x198.jpg" alt="" width="300" height="198" /></a><p class="wp-caption-text">Eniac的电子管阵列</p></div>
<div id="attachment_464" class="wp-caption alignleft" style="width: 310px"><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/vintage_computers_10.jpg" rel="lightbox[462]"><img class="size-medium wp-image-464 " style="border: 0pt none;" title="Core Memory 肉眼能够看到的1比特" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/vintage_computers_10-300x198.jpg" alt="" width="300" height="198" /></a><p class="wp-caption-text">Core Memory 肉眼能够看到的1比特</p></div>
<p style="clear: left;">这本书是2007年出版的，这么久了，在国内却一直不知道……<span id="more-462"></span></p>
<h2>游戏书</h2>
<p>日本在游戏市场和游戏开发领域都在世界的前列。游戏方面自然也有不少书（当然不是指游戏攻略……）。</p>
<p>最注目的是这本 <a href="http://www.amazon.co.jp/dp/4862461468" target="_blank">《死ぬまでにやりたいゲーム1001》（到死也想玩的1001款游戏）</a>，看封面就知道这是本纵贯游戏史的作品了。960页的容量，让其成为名副其实的砖头。看着这些亲切的画面，确实能引起70、80年代的人很强烈的共鸣。这些游戏不仅在当时是划时代的创新，也为后来整个游戏行业的发展奠定了基础。</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/game1001.jpg" rel="lightbox[462]"><img class="alignnone size-medium wp-image-474" style="border: 0pt none;" title="game1001" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/game1001-300x300.jpg" alt="" width="300" height="300" /></a><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/game1001-2.jpg" rel="lightbox[462]"><img class="alignnone size-medium wp-image-473" style="border: 0pt none;" title="game1001-2" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/game1001-2-300x300.jpg" alt="" width="300" height="300" /></a></p>
<p>另外一个书架上有许多游戏开发的书，主要都是与游戏相关的数学、物理、AI方面的书。其中有一本叫<a href="http://cgi32.plala.or.jp/higpen/book/bullet/bullet.shtml" target="_blank">《弾幕 最強のシューティングゲームを作る！》（弹幕 制作最强的射击游戏）</a>吸引了我。翻开一看，其实都是些公式和程序，顾名思义，就是教你怎么设计弹幕的。以前只知道很多射击游戏的弹幕很变态，原来弹幕的设计也有这么多学问…… 那些骨灰级玩家是不是都研究过弹幕的算法的呀？</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-cover.jpg" rel="lightbox[462]"><img class="alignnone size-thumbnail wp-image-483" style="border: 0pt none; margin-left: 5px; margin-right: 5px;" title="danmaku-cover" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-cover-150x150.jpg" alt="" width="150" height="150" /></a><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample1.png" rel="lightbox[462]"><img class="alignnone size-thumbnail wp-image-479" style="border: 0pt none; margin-left: 5px; margin-right: 5px;" title="danmaku-sample1" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample1-150x150.png" alt="" width="150" height="150" /></a><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample2.png" rel="lightbox[462]"><img class="alignnone size-thumbnail wp-image-480" style="border: 0pt none; margin-left: 5px; margin-right: 5px;" title="danmaku-sample2" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample2-150x150.png" alt="" width="150" height="150" /></a><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample3.png" rel="lightbox[462]"><img class="alignnone size-thumbnail wp-image-481" style="margin-left: 5px; margin-right: 5px; border: 0pt none;" title="danmaku-sample3" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2012/01/danmaku-sample3-150x150.png" alt="" width="150" height="150" /></a></p>
<h2>开发人员工作方法</h2>
<p>有几本关于工作方法的书不错，不过鉴于时间原因，没有细看。</p>
<p>1.<a href="http://www.amazon.co.jp/dp/4873114039" target="_blank">《リファクタリング・ウェットウェア ―達人プログラマーの思考法と学習法》</a></p>
<ul>
<li>中文版<a href="http://book.douban.com/subject/5372651/" target="_blank">《程序员的思维修炼》</a></li>
<li>原版      <a href="http://pragprog.com/book/ahptl/pragmatic-thinking-and-learning" target="_blank">Pragmatic Thinking and Learning: Refactor Your Wetware</a></li>
</ul>
<p>2. <a href="http://www.amazon.co.jp/dp/4873115051" target="_blank">《ゲームストーミング ―会議、チーム、プロジェクトを成功へと導く87のゲーム》</a></p>
<ul>
<li><a href="http://amzn.com/0596804172" target="_blank">Game Storming: A Playbook for Innovators, Rulebreakers, and Changemakers </a></li>
</ul>
<p>3. <a href="http://www.amazon.co.jp/dp/4844329944" target="_blank">《エンジニアとして生き方》(IT工程师的生活方式)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2012/01/new-year-book-hunting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我的2011</title>
		<link>http://www.think-in-g.net/ghawk/blog/2011/12/summary-of2011/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2011/12/summary-of2011/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 13:53:06 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[生活琐事]]></category>
		<category><![CDATA[2011]]></category>
		<category><![CDATA[回顾]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[年度总结]]></category>
		<category><![CDATA[新年]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=450</guid>
		<description><![CDATA[离2011年结束只有几小时了。就以这篇日志送走2011迎来新的一年吧！ 2011年是我人生中重要的一年，因为这一年，我满30岁了。中国人说三十而立，虽然只有四个字，却着实带有分量，这一年中我有了不少变化。这些变化和经历也让今年变得精彩纷呈。 新的生活 首先，也是最重要的，在生活上，我开始学习怎么做一个父亲。不过，说实在的，我在这方面做得很不够，除了逗绯麟玩，其他很多事情都是太太在操心着，这真的非常感谢太太为这个家庭所付出的一切！不过好在在逗小孩方面，我貌似比我爹强一点（根据我妈口述的历史推断的），在怎么当一个好爸爸方面，我会加油的。 在业余爱好方面，我开始了解摄影。其实对于摄影，我本来并不是兴趣很浓，很多都是源于太太的爱好。但是当我读了Joe McNally的《瞬间的背后（The moment it clicks）》之后，我感受到了摄影的魅力，一副好的照片不仅仅定格了一个瞬间，更重要的是它承载了一种意义，试图让观众产生思考和共鸣，告诉他们照片背后的故事。于是我开始学着在按下快门的时候去思考，尽管现在还只是业余中的业余，但是我觉得我的方向是正确的，我不烧器材，最重要的限制并不是器材，而是自己。 另外，自从买了一台咖啡机，我还喜欢上了拿铁艺术，咖啡师的精湛技艺让我着迷，于是我学者自己做咖啡，了解牛奶的特性。5月份在东京还去了WBC世界冠军澤田洋史的咖啡馆，亲自体验到了大师的手艺～ 也因为如此，我知道了像星巴克这样的量产式连锁咖啡店是很少能做出像样的意式咖啡的，因为从那些店员的手势中可以看出他们大多对咖啡没有爱，他们只把在咖啡机前萃取咖啡当成日常工作。所以，要喝好咖啡，就应该找一个有barista而不是waiter/waitress的地方。就像程序员应该与程序员为伍，而要远离打字员。 新的工作 新的工作并不是说我又换工作了，只是多了些不同的工作经历。继去年的互联网社交平台之后，我依旧为公司在互联网方面的发展服务着。 在年中的时候，公司在互联网方面的战略有了变化。由于此前在社交平台方面的尝试并不是很成功，所以公司将主要方向有转回了比较稳定且熟悉的广告行业。这一变化一度使得上海分公司失去了清晰的角色定位。受此影响，上海方面的开发团队终止了很多原有的开发计划，转变为维护体制，时忙时闲。 6月份的时候，由于日本方面的智能手机出现了井喷式增长的苗头（各大厂商纷纷推出自己的Android智能终端），公司决定将传统的广告业务向智能手机拓展。机缘巧合地，我开始了iOS的开发。得到这个机会，也许是因为我此前曾提出过想尝试iOS开发，也许是没有选择的选择，因为相比之下，我实在对perl没什么兴趣。 成为苹果开发者，可以说是我职业生涯中一段奇妙的旅程。正如我在微博上所说的：“转眼已经年底了，还记得半年前复活了那台老MBP，看着CS193P，开始学写语法怪异的Objective-C的日子。那种神奇的感觉，就像15年前误打误撞地接触到了VB 4.0……” 是的，没错，我感觉自己又回到了那个充满好奇心和探索欲望的时代。 年底前，为了一个新项目，一直忙到全公司放假的那天。虽然忙碌，但是我学到了很多。趁着年假之际，我正在补习WWDC 2011的讲座，这些东西让我有了不少想法，接下来是要稳扎稳打一步一步去实现。 我们公司的工程师团队氛围十分自由，并不像传统的日本式的SI公司，大家经常会办些交流活动，业余时间大家基本也都有自己的项目。在工作的余暇，我也尝试着做些有意思、有意义的事情。 今年翻译了两本书，一本与互联网广告和营销有关，另一本与云计算平台中的应用开发有关，翻译工作确实很辛苦。幸运的是，这两本书多少都与我的工作经验有点关系，也正好能够填补我在工作中的一些知识断层。不过由于本人语言文字的基础并不是很扎实，所以语言方面还是处理得比较直白，也可能不够风趣幽默引人入胜，不知道最后反响会怎样。 在体验OS X Lion时，感觉在全屏模式的下确认输入法有些不便，于是我抽空写了isHUD，并开放了全部核心代码，后来包装了一下界面，把它放到Mac App Store上去了。尽管销售方面基本无人问津，但这整个过程让我收获颇多。也为我在明年做些业余小作品增加了不少信心。 新的朋友 要感谢微博，今年通过这个平台结识了很多新朋友。有爱好柯基的狗友，有出版社的编辑老师，有技术圈中的活跃人士…… 人数众多，在此就不一一点名列举了。要感谢这些朋友，他们跟我一起分享快乐，一起分享新的知识、探讨问题。这是互联网的力量，就像n年前网易的广告词“网聚人的力量”。 新的装备 在今年夏天，陪伴我多年的T61因显卡门问题多次故障，前前后后修理了三次，最后我放弃了，于是，我的第一台Thinkpad（可能也是最后一台，因为现在的联想似乎已经失去了对Thinkpad产品线的关注）就那么静静地躺在那儿休息，或许什么时候我还会召唤他，复活他，但不是现在。 后来，我买了一台Macbook Air，这是个称手的好工具，干活娱乐两不误。作为长期的Linux用户，切换到Mac基本没有什么障碍。 没有相机的日子总觉得缺点什么，比较再三，入了一台E-PL3（谁知相机刚到手，奥林巴斯就曝出丑闻……囧rz），用着很称手，非常喜欢这台机器。 新的坐标 8月底的时候，我来到了日本，开始了长期单身赴任的生活。 现在我住在川崎市，每天挤小田急电铁上下班，挤到什么程度我就不形容了，呵呵～ 刚到日本时遇到不少麻烦，因为信用卡总是办不下来，很多东西都不方便。后来东西慢慢置办齐了，生活也渐渐步入正轨了。也请国内的家人和朋友放心，现在一切都挺好的。 One More Thing 本年度对我影响最大的书有两本，一本是之前提到过的《瞬间的背后》。另一本是《黑客与画家》，具体为什么就不说了，相信看过的人会有共鸣的。感谢图灵和阮一峰老师给我带来此优秀的作品！ 2012 2012，我有很多想做的。所以，首先希望世界不要终结！ 然后，就相信自己去做吧！我要不断寻找真正的自己！ 最后，祝愿家人和朋友们新年快乐！健康、幸福！]]></description>
			<content:encoded><![CDATA[<p>离2011年结束只有几小时了。就以这篇日志送走2011迎来新的一年吧！</p>
<p>2011年是我人生中重要的一年，因为这一年，我满30岁了。中国人说三十而立，虽然只有四个字，却着实带有分量，这一年中我有了不少变化。这些变化和经历也让今年变得精彩纷呈。<span id="more-450"></span></p>
<h3><strong><em>新的生活</em></strong></h3>
<p>首先，也是最重要的，在生活上，我开始学习怎么做一个父亲。不过，说实在的，我在这方面做得很不够，除了逗绯麟玩，其他很多事情都是太太在操心着，这真的非常感谢太太为这个家庭所付出的一切！不过好在在逗小孩方面，我貌似比我爹强一点（根据我妈口述的历史推断的），在怎么当一个好爸爸方面，我会加油的。</p>
<p>在业余爱好方面，我开始了解摄影。其实对于摄影，我本来并不是兴趣很浓，很多都是源于太太的爱好。但是当我读了Joe McNally的《瞬间的背后（The moment it clicks）》之后，我感受到了摄影的魅力，一副好的照片不仅仅定格了一个瞬间，更重要的是它承载了一种意义，试图让观众产生思考和共鸣，告诉他们照片背后的故事。于是我开始学着在按下快门的时候去思考，尽管现在还只是业余中的业余，但是我觉得我的方向是正确的，我不烧器材，最重要的限制并不是器材，而是自己。</p>
<p>另外，自从买了一台咖啡机，我还喜欢上了拿铁艺术，咖啡师的精湛技艺让我着迷，于是我学者自己做咖啡，了解牛奶的特性。5月份在东京还去了WBC世界冠军澤田洋史的咖啡馆，亲自体验到了大师的手艺～ 也因为如此，我知道了像星巴克这样的量产式连锁咖啡店是很少能做出像样的意式咖啡的，因为从那些店员的手势中可以看出他们大多对咖啡没有爱，他们只把在咖啡机前萃取咖啡当成日常工作。所以，要喝好咖啡，就应该找一个有barista而不是waiter/waitress的地方。就像程序员应该与程序员为伍，而要远离打字员。</p>
<h3><strong><em>新的工作</em></strong></h3>
<p>新的工作并不是说我又换工作了，只是多了些不同的工作经历。继去年的互联网社交平台之后，我依旧为公司在互联网方面的发展服务着。</p>
<p>在年中的时候，公司在互联网方面的战略有了变化。由于此前在社交平台方面的尝试并不是很成功，所以公司将主要方向有转回了比较稳定且熟悉的广告行业。这一变化一度使得上海分公司失去了清晰的角色定位。受此影响，上海方面的开发团队终止了很多原有的开发计划，转变为维护体制，时忙时闲。</p>
<p>6月份的时候，由于日本方面的智能手机出现了井喷式增长的苗头（各大厂商纷纷推出自己的Android智能终端），公司决定将传统的广告业务向智能手机拓展。机缘巧合地，我开始了iOS的开发。得到这个机会，也许是因为我此前曾提出过想尝试iOS开发，也许是没有选择的选择，因为相比之下，我实在对perl没什么兴趣。</p>
<p>成为苹果开发者，可以说是我职业生涯中一段奇妙的旅程。正如我在微博上所说的：“转眼已经年底了，还记得半年前复活了那台老MBP，看着CS193P，开始学写语法怪异的Objective-C的日子。那种神奇的感觉，就像15年前误打误撞地接触到了VB 4.0……” 是的，没错，我感觉自己又回到了那个充满好奇心和探索欲望的时代。</p>
<p>年底前，为了一个新项目，一直忙到全公司放假的那天。虽然忙碌，但是我学到了很多。趁着年假之际，我正在补习WWDC 2011的讲座，这些东西让我有了不少想法，接下来是要稳扎稳打一步一步去实现。</p>
<p>我们公司的工程师团队氛围十分自由，并不像传统的日本式的SI公司，大家经常会办些交流活动，业余时间大家基本也都有自己的项目。在工作的余暇，我也尝试着做些有意思、有意义的事情。</p>
<p>今年翻译了两本书，一本与互联网广告和营销有关，另一本与云计算平台中的应用开发有关，翻译工作确实很辛苦。幸运的是，这两本书多少都与我的工作经验有点关系，也正好能够填补我在工作中的一些知识断层。不过由于本人语言文字的基础并不是很扎实，所以语言方面还是处理得比较直白，也可能不够风趣幽默引人入胜，不知道最后反响会怎样。</p>
<p>在体验OS X Lion时，感觉在全屏模式的下确认输入法有些不便，于是我抽空写了isHUD，并开放了全部核心代码，后来包装了一下界面，把它放到Mac App Store上去了。尽管销售方面基本无人问津，但这整个过程让我收获颇多。也为我在明年做些业余小作品增加了不少信心。</p>
<h3><strong><em>新的朋友</em></strong></h3>
<p>要感谢微博，今年通过这个平台结识了很多新朋友。有爱好柯基的狗友，有出版社的编辑老师，有技术圈中的活跃人士…… 人数众多，在此就不一一点名列举了。要感谢这些朋友，他们跟我一起分享快乐，一起分享新的知识、探讨问题。这是互联网的力量，就像n年前网易的广告词“网聚人的力量”。</p>
<h3><strong><em>新的装备</em></strong></h3>
<p>在今年夏天，陪伴我多年的T61因显卡门问题多次故障，前前后后修理了三次，最后我放弃了，于是，我的第一台Thinkpad（可能也是最后一台，因为现在的联想似乎已经失去了对Thinkpad产品线的关注）就那么静静地躺在那儿休息，或许什么时候我还会召唤他，复活他，但不是现在。</p>
<p>后来，我买了一台Macbook Air，这是个称手的好工具，干活娱乐两不误。作为长期的Linux用户，切换到Mac基本没有什么障碍。</p>
<p>没有相机的日子总觉得缺点什么，比较再三，入了一台E-PL3（谁知相机刚到手，奥林巴斯就曝出丑闻……囧rz），用着很称手，非常喜欢这台机器。</p>
<h3><strong><em>新的坐标</em></strong></h3>
<p>8月底的时候，我来到了日本，开始了长期单身赴任的生活。</p>
<p>现在我住在川崎市，每天挤小田急电铁上下班，挤到什么程度我就不形容了，呵呵～</p>
<p>刚到日本时遇到不少麻烦，因为信用卡总是办不下来，很多东西都不方便。后来东西慢慢置办齐了，生活也渐渐步入正轨了。也请国内的家人和朋友放心，现在一切都挺好的。</p>
<h3><strong><em>One More Thing</em></strong></h3>
<p>本年度对我影响最大的书有两本，一本是之前提到过的《瞬间的背后》。另一本是《黑客与画家》，具体为什么就不说了，相信看过的人会有共鸣的。感谢图灵和阮一峰老师给我带来此优秀的作品！</p>
<h3><em><strong>2012</strong></em></h3>
<p>2012，我有很多想做的。所以，首先希望世界不要终结！</p>
<p>然后，就相信自己去做吧！我要不断寻找真正的自己！</p>
<p><span style="font-size: large;">最后，祝愿家人和朋友们新年快乐！健康、幸福！</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2011/12/summary-of2011/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>架构师的选择（觉悟）</title>
		<link>http://www.think-in-g.net/ghawk/blog/2011/11/the-selection-of-architect/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2011/11/the-selection-of-architect/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 07:15:13 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[翻译]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[architect]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=443</guid>
		<description><![CDATA[原文链接：アーキテクトの選択（あるいは覚悟） 架构师的工作大部分时间都是在“做选择”，这些选择都是在一切发生之前所做出的，因此，一旦决定就不能更改了。 架构师所要选择的是静态的结构。方案一旦确定，就开始转入退化过程。随着时间的推移，系统的适应性会变差，对做出的决定进行修改往往要付出巨大的代价。 当然，项目经理对于进度计划以及项目人员体制等方面的安排也属于“事先选择”。但是，这些选择对象都属于动态的过程。 动态的过程能够随着时间的推移适应其过程中出现的变化。包括敏捷等迭代式过程在内的开发过程，它们都推荐在开发过程中设立短期目标并根据实际作业情况做出调整。这是非常有效的方法。动态过程承认事先选择中所发生的过失和偏差，且允许在事情发生之后做出改变。 有这么一说：“Good managers do things right （优秀的管理者会做正确的事）”，项目经理所做的是把握事先选择（计划）和事后情况（实际）两者之间的偏差，针对这些偏差对各种各样的参数做出调整，将项目的发展方向始终沿着预定的轨道不断进行修正。 然而，架构师的选择却是静态的结构，敏捷的推进方式无法适用于这些静态结构。 对于静态结构而言，PO（Proof of concept/概念验证）或是建立原型等“基于尝试进行评价”的方法才是有效的。PO或原型等手段能够降低风险，促成事先选择，尽管如此，要让选择后的结果能够适应事后的变化，这些方法仍然无能为力。 那么，在这种情况下，架构师该如何做出选择呢？ 《软件架构师应该知道的97件事》 中有篇文章：“24：重视不确定性 ”。 Confronted with two options, most people think that the most important thing to do is to make a choice between them. In design (software or otherwise), it is not. The presence of two options is an [...]]]></description>
			<content:encoded><![CDATA[<p>原文链接：<a title="アーキテクトの選択（あるいは覚悟）" href="http://www.arclamp.jp/blog/archives/architect_no_sentaku.html" target="_blank">アーキテクトの選択（あるいは覚悟）</a></p>
<p><strong>架构师的工作大部分时间都是在“做选择”，这些选择都是在一切发生之前所做出的，因此，一旦决定就不能更改了。</strong></p>
<p>架构师所要选择的是静态的结构。方案一旦确定，就开始转入退化过程。随着时间的推移，系统的适应性会变差，对做出的决定进行修改往往要付出巨大的代价。</p>
<p>当然，项目经理对于进度计划以及项目人员体制等方面的安排也属于“事先选择”。但是，这些选择对象都属于动态的过程。</p>
<p>动态的过程能够随着时间的推移适应其过程中出现的变化。包括敏捷等迭代式过程在内的开发过程，它们都推荐在开发过程中设立短期目标并根据实际作业情况做出调整。这是非常有效的方法。动态过程承认事先选择中所发生的过失和偏差，且允许在事情发生之后做出改变。</p>
<p>有这么一说：“Good managers do things right （优秀的管理者会做正确的事）”，<strong>项目经理所做的是把握事先选择（计划）和事后情况（实际）两者之间的偏差，针对这些偏差对各种各样的参数做出调整，将项目的发展方向始终沿着预定的轨道不断进行修正。</strong></p>
<p>然而，<strong>架构师的选择却是静态的结构，敏捷的推进方式无法适用于这些静态结构</strong>。</p>
<p><span id="more-443"></span>对于静态结构而言，PO（Proof of concept/概念验证）或是建立原型等“基于尝试进行评价”的方法才是有效的。<strong>PO或原型等手段能够降低风险，促成事先选择</strong>，尽管如此，要让选择后的结果能够适应事后的变化，这些方法仍然无能为力。</p>
<p>那么，在这种情况下，架构师该如何做出选择呢？</p>
<p><a href="http://oreilly.com.cn/index.php?func=book&amp;isbn=978-7-121-10635-4">《软件架构师应该知道的97件事》</a> 中有篇文章：<a href="http://97things.oreilly.com/wiki/index.php/Use_uncertainty_as_a_driver">“24：重视不确定性 ”</a>。</p>
<blockquote><p>Confronted with two options, most people think that the most important thing to do is to make a choice between them. In design (software or otherwise), it is not. The presence of two options is an indicator that you need to consider uncertainty in the design. Use the uncertainty as a driver to determine where you can defer commitment to details and where you can partition and abstract to reduce the significance of design decisions. If you hardwire the first thing that comes to mind you’re more likely to be stuck with it, so that incidental decisions become significant and the softness of the software is reduced.</p>
<p>当眼前出现两个选项的时候，基本上任何人都会将选择哪个作为最重要的事情去考虑。但是，在设计（软件也不例外）中却不是这样。出现两个选项的情况就是一种信号，告诉你应该考虑该设计中所潜藏着的不确定性。</p></blockquote>
<p>这一篇的作者Kevlin提到“在无法做出选择时，要先停一停，退回去想想”。虽然这一点非常重要，但是在项目中，无论如何，让别人停下等是不行的。就这么等着，直到某一天做出选择，进度上就难以保证了。</p>
<p>正因为如此，<strong>为了做出“必须这么做才行”的决定，架构师要尽其所能地做到眼前所能做的一切，这一点就显得格外重要了</strong>。</p>
<p>对于不同的选择项，真正让你无从选择的原因是因为你无法确定判断的基准。因此，问题的重点在于寻找判断基准。</p>
<p>优秀的架构师总是能够缩小“判断”其本身对整个过程的影响。不管选择哪种架构，多少都是带着自信去选择的。但是，仅仅这样是无法得到“必须这么做才行”的理由的。</p>
<p>也就是说，要做出判断，不能仅凭眼前的基准，而是一定要找到某些能够起到决定性作用的参数。这些参数应该兼顾对时间和空间上的考虑。</p>
<p>1年后会怎么样？2年后呢？3年呢？</p>
<p>程序员的观点是什么？PM的观点是什么？用户的观点是什么？运维人员的观点是什么？</p>
<p>带着这些问题去考虑，拓展利益相关人（stakeholder）的观点，寻找用于判断的基准。单凭想象是不够的，所以亲自去了解一下各方的意见吧。这些利益相关人自身的行事原理和依据是什么？确立一个能提炼出判断基准的行动方针，去寻找答案吧！</p>
<p>这样，才能得到“必须这么做才行”的理由。</p>
<p><strong>倘若不论怎么努力都无法得到“必须这么做才行”的理由，你一定会意识到其中所存在的不足。</strong> 这样就无法为这个选择而负责，或直面未来会产生的风险。</p>
<p>也许你会做出的选择并不正确。但是，一定要有“必须这么做才行”的绝对自信。为了做出“必须这么做才行的决定”而不断努力，最后选择了与自己的直觉最接近的方案，要坚定这样的想法。</p>
<p>如果没有这样的觉悟，是无法说服自己做出“必须这么做才行”的抉择的。不论项目的规模是大是小，架构方面的决定都将影响到与项目有关的很多人。架构师应该始终牢记这一点。</p>
<p>权力并不是事先给予你的，而是随着责任意识越来越强，权力会越来越大。架构师有了这种意识，无论面对谁，都能胸有成竹地回答：“这是正确的选择/这样做没错的。”</p>
<p>未来总是不确定的。但是，我们只能在现有的选项中进行取舍。<strong>为了做出“必须这么做才行”的抉择，要对战略方针进行推敲，而这不正是被称为“架构师”的这群人们其工作的本质吗？</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2011/11/the-selection-of-architect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>isHUD v0.2发布声明</title>
		<link>http://www.think-in-g.net/ghawk/blog/2011/11/ishud-v0-2-release-notes/</link>
		<comments>http://www.think-in-g.net/ghawk/blog/2011/11/ishud-v0-2-release-notes/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 13:49:38 +0000</pubDate>
		<dc:creator>ghawk.gu</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[软件]]></category>
		<category><![CDATA[HUD]]></category>
		<category><![CDATA[input source]]></category>
		<category><![CDATA[isHUD]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[utility]]></category>
		<category><![CDATA[辅助工具]]></category>
		<category><![CDATA[输入法]]></category>

		<guid isPermaLink="false">http://www.think-in-g.net/ghawk/blog/?p=431</guid>
		<description><![CDATA[isHUD v0.2发布声明 目的 作为一个多语言的Mac OS X用户，我使用系统默认的快捷键（Command+空格, Option+Command+空格）切换输入法。但是，当我按下Option+Command+空格（即选择下一个输入源）的时候，系统并不会出现输入法选择框（按Command+空格时候出现的那个列表）。当启用的Lion的全屏模式的时候，要确认当前所使用的输入法十分不便。 于是isHUD诞生了！isHUD是“input source HUD”的缩写。 有了isHUD，每当切换输入法的时候，屏幕中央就会出现一个HUD窗口，提示选中的输入法，这样，你无须移动视线就能知道所选的输入法了。 如果你想要更快捷地切换输入法，那么这篇博客也许对你有用。其中也提到了为什么要做isHUD。 相关链接 isHUD 下载链接：isHUD-v0.2.zip github主页 中文README 日语README 系统运行环境 Mac OS X 10.6.x(Snow Leopard)+ 构建环境 Mac OS X 10.7.2(Lion) XCode 4.2 许可证 isHUD 基于 MIT 许可证。你可以随意使用该应用程序以及相关的源码。 反馈 如果你觉得isHUD不错或是有什么问题，请发邮件告诉我 。我会进一步对其进行改进。另外，除了汉语之外，我还使用日语和英语，所以请使用这些语言发邮件。谢谢！ 接下来的计划 把图标做得漂亮些，欢迎有灵感的朋友帮忙！ 考虑是不是要增加一个偏好设置，增加一些自定义的设置。]]></description>
			<content:encoded><![CDATA[<h1 id="ishud-osxhud">isHUD v0.2发布声明</h1>
<h2>目的</h2>
<p>作为一个多语言的Mac OS X用户，我使用系统默认的快捷键（Command+空格, Option+Command+空格）切换输入法。但是，当我按下Option+Command+空格（即选择下一个输入源）的时候，系统并不会出现输入法选择框（按Command+空格时候出现的那个列表）。当启用的Lion的全屏模式的时候，要确认当前所使用的输入法十分不便。</p>
<p>于是isHUD诞生了！isHUD是“input source HUD”的缩写。</p>
<p>有了isHUD，每当切换输入法的时候，屏幕中央就会出现一个HUD窗口，提示选中的输入法，这样，你无须移动视线就能知道所选的输入法了。</p>
<p><a href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2011/11/isHUD-screenshot-chs.jpg" rel="lightbox[431]"><img class="alignnone size-medium wp-image-426" title="isHUD-截图" src="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2011/11/isHUD-screenshot-chs.jpg" alt="" width="80%" /></a></p>
<p>如果你想要更快捷地切换输入法，那么<a href="http://www.think-in-g.net/ghawk/blog/2011/11/os-x-mappging-a-single-key-to-select-input-source/">这篇博客也许对你有用</a>。其中也提到了为什么要做isHUD。</p>
<p><span id="more-431"></span></p>
<h2>相关链接</h2>
<ul>
<li>isHUD 下载链接：<a title="isHUD-v0.2.zip" href="http://www.think-in-g.net/ghawk/blog/wp-content/uploads/2011/11/isHUD-v0.2.zip" target="_blank">isHUD-v0.2.zip</a></li>
<li><a href="https://github.com/ghawkgu/isHUD" target="_blank">github主页</a></li>
<li><a href="https://github.com/ghawkgu/isHUD/blob/master/README_chs.md" target="_blank">中文README</a></li>
<li><a href="https://github.com/ghawkgu/isHUD/blob/master/README_jpn.md" target="_blank">日语README</a></li>
</ul>
<h2>系统运行环境</h2>
<ul>
<li>Mac OS X 10.6.x(Snow Leopard)+</li>
</ul>
<h2>构建环境</h2>
<ul>
<li>Mac OS X 10.7.2(Lion)</li>
<li>XCode 4.2</li>
</ul>
<h2>许可证</h2>
<p>isHUD 基于 MIT 许可证。你可以随意使用该应用程序以及相关的源码。</p>
<h2>反馈</h2>
<p>如果你觉得isHUD不错或是有什么问题，请发邮件告诉我 。我会进一步对其进行改进。另外，除了汉语之外，我还使用日语和英语，所以请使用这些语言发邮件。谢谢！</p>
<h2>接下来的计划</h2>
<ul>
<li>把图标做得漂亮些，欢迎有灵感的朋友帮忙！</li>
<li>考虑是不是要增加一个偏好设置，增加一些自定义的设置。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.think-in-g.net/ghawk/blog/2011/11/ishud-v0-2-release-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

