<?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>iPhoneGeek 爱疯极客</title>
	<atom:link href="http://www.iphone-geek.cn/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iphone-geek.cn</link>
	<description>iPhone 新闻，编程，技巧与提示，代码，教程</description>
	<lastBuildDate>Tue, 09 Mar 2010 03:13:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>OpenGL ES纹理尺寸限制的处理方法</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:13:34 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=916</guid>
		<description><![CDATA[大家都知道，OpenGL ES对纹理的尺寸有限制，就是长和宽都必须是2的整数次幂。（实际上OpenGL都有此限制，但有一些扩展可以解决此问题）。因此处理方案有两种：


将纹理尺寸限制为2的整数次幂。比如，我有一个480&#215;320的背景图案，我可以用Photoshop将画布设置为512&#215;512，在纹理映射时只使用480&#215;320部分。当然我也可以将多个图案合成在一个纹理中，在纹理映射时根据图案的位置进行映射。 
仍然使用正常的图像尺寸，但在使用时进行转换。下面是源代码：


1234567891011121314151617181920212223242526&#160; &#160; &#160; &#160; // 首先调整纹理的长和宽为2的整数次幂 &#160; &#160; &#160; &#160; 
&#160; &#160; &#160; &#160; if&#40; &#40;_width != 1&#41; &#38;&#38; &#40;_width &#38; &#40;_width - 1&#41;&#41; &#41;
&#160; &#160; &#160; &#160; &#123;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; i = 1;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; while&#40;&#40;sizeToFit ? 2 * i : i&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>大家都知道，OpenGL ES对纹理的尺寸有限制，就是长和宽都必须是2的整数次幂。（实际上OpenGL都有此限制，但有一些扩展可以解决此问题）。因此处理方案有两种：</p>
<p><br class="spacer_" /></p>
<ol>
<li>将纹理尺寸限制为2的整数次幂。比如，我有一个480&#215;320的背景图案，我可以用Photoshop将画布设置为512&#215;512，在纹理映射时只使用480&#215;320部分。当然我也可以将多个图案合成在一个纹理中，在纹理映射时根据图案的位置进行映射。 </li>
<li>仍然使用正常的图像尺寸，但在使用时进行转换。下面是源代码：</li>
</ol>
<p><br class="spacer_" /></p>
<p><div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// 首先调整纹理的长和宽为2的整数次幂 &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">!</span><span style="color: #000080;">=</span> 1<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">-</span> 1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>sizeToFit <span style="color: #008080;">?</span> 2 <span style="color: #000040;">*</span> i <span style="color: #008080;">:</span> i<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> _width<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _width <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">!</span><span style="color: #000080;">=</span> 1<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">-</span> 1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>sizeToFit <span style="color: #008080;">?</span> 2 <span style="color: #000040;">*</span> i <span style="color: #008080;">:</span> i<span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> _height<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _height <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// 如果调整后的图像尺寸大于最大纹理尺寸（1024），那么需要缩小</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>_width <span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span> kMaxTextureSize<span style="color: #008000;">&#41;</span> <span style="color: #000040;">||</span> <span style="color: #008000;">&#40;</span>_height <span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span> kMaxTextureSize<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _width <span style="color: #000040;">/</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _height <span style="color: #000040;">/</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transform <span style="color: #000080;">=</span> CGAffineTransformScale<span style="color: #008000;">&#40;</span>transform, 0.5, 0.5<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageSize.<span style="color: #007788;">x</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color:#800080;">0.5</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageSize.<span style="color: #007788;">y</span> <span style="color: #000040;">*</span><span style="color: #000080;">=</span> <span style="color:#800080;">0.5</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es%e7%ba%b9%e7%90%86%e5%b0%ba%e5%af%b8%e9%99%90%e5%88%b6%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL ES 3D物体加载示例</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es-3d%e7%89%a9%e4%bd%93%e5%8a%a0%e8%bd%bd%e7%a4%ba%e4%be%8b</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es-3d%e7%89%a9%e4%bd%93%e5%8a%a0%e8%bd%bd%e7%a4%ba%e4%be%8b#comments</comments>
		<pubDate>Wed, 03 Mar 2010 03:50:59 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[开源项目]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=912</guid>
		<description><![CDATA[前几天有位朋友向我询问有关3D物体加载的示例，记得以前看到过一个示例，就找来出来与大家分享：

iPhone Wavefront Obj Loader

]]></description>
			<content:encoded><![CDATA[<p>前几天有位朋友向我询问有关3D物体加载的示例，记得以前看到过一个示例，就找来出来与大家分享：</p>
<p><br class="spacer_" /></p>
<p><a title="iPhone Wavefront Loader" href="http://code.google.com/p/iphonewavefrontloader/">iPhone Wavefront Obj Loader</a></p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/opengl-es-3d%e7%89%a9%e4%bd%93%e5%8a%a0%e8%bd%bd%e7%a4%ba%e4%be%8b/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple禁止越狱者访问App Store？</title>
		<link>http://www.iphone-geek.cn/%e6%96%b0%e9%97%bb/apple%e7%a6%81%e6%ad%a2%e8%b6%8a%e7%8b%b1%e8%80%85%e8%ae%bf%e9%97%aeapp-store%ef%bc%9f</link>
		<comments>http://www.iphone-geek.cn/%e6%96%b0%e9%97%bb/apple%e7%a6%81%e6%ad%a2%e8%b6%8a%e7%8b%b1%e8%80%85%e8%ae%bf%e9%97%aeapp-store%ef%bc%9f#comments</comments>
		<pubDate>Tue, 02 Mar 2010 03:48:36 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[新闻]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/uncategorized/apple%e7%a6%81%e6%ad%a2%e8%b6%8a%e7%8b%b1%e8%80%85%e8%ae%bf%e9%97%aeapp-store%ef%bc%9f</guid>
		<description><![CDATA[据称部分越狱者在“越狱”iPhone OS 3.1.3后，出现以下问题：
&#160;
 
&#160;
是否Apple开始了“反越狱”行动，目前还不得而知。不过要是无法使用“越狱”的iPhone，我相信iPhone的使用者将大幅度地减少，你认为呢？
&#160;
参见：http://www.examiner.com/x-8134-SF-Gadgets-Examiner~y2010m2d15-Apple-might-be-banning-iPhone-hackers
]]></description>
			<content:encoded><![CDATA[<p>据称部分越狱者在“越狱”iPhone OS 3.1.3后，出现以下问题：</p>
<p>&#160;</p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/03/image1.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.iphone-geek.cn/wp-content/uploads/2010/03/image_thumb1.png" width="262" height="361" /></a> </p>
<p>&#160;</p>
<p>是否Apple开始了“反越狱”行动，目前还不得而知。不过要是无法使用“越狱”的iPhone，我相信iPhone的使用者将大幅度地减少，你认为呢？</p>
<p>&#160;</p>
<h5>参见：<a title="http://www.examiner.com/x-8134-SF-Gadgets-Examiner~y2010m2d15-Apple-might-be-banning-iPhone-hackers" href="http://www.examiner.com/x-8134-SF-Gadgets-Examiner~y2010m2d15-Apple-might-be-banning-iPhone-hackers">http://www.examiner.com/x-8134-SF-Gadgets-Examiner~y2010m2d15-Apple-might-be-banning-iPhone-hackers</a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e6%96%b0%e9%97%bb/apple%e7%a6%81%e6%ad%a2%e8%b6%8a%e7%8b%b1%e8%80%85%e8%ae%bf%e9%97%aeapp-store%ef%bc%9f/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>iPad/iPhone与多任务</title>
		<link>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipadiphone%e4%b8%8e%e5%a4%9a%e4%bb%bb%e5%8a%a1</link>
		<comments>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipadiphone%e4%b8%8e%e5%a4%9a%e4%bb%bb%e5%8a%a1#comments</comments>
		<pubDate>Mon, 01 Mar 2010 04:11:38 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[闲谈]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipadiphone%e4%b8%8e%e5%a4%9a%e4%bb%bb%e5%8a%a1</guid>
		<description><![CDATA[最近很忙再加上新年，所以很久没有更新博客了，抱歉。
&#160;
苹果即将推出的iPad到底具有哪些功能，可谓是众说纷纭。我最为关心的问题是到底iPad是否支持多任务，种种迹象表明答案是否定的。这让许多开发者包括我自己十分失望。缺乏多任务支持使得许多简单的功能都无法实现。记得一位朋友问过我关于在iPhone上实现闹钟功能的问题，这实在是一个简单的程序，可是在没有破解的iPhone上却没办法实现。（准确地说，是无法完美实现。你当然可以写一个运行于前台的闹钟程序，不再运行其它程序，可是它有多实用呢？另外还可以用Push Notification技术，不过这实在有点“大炮打蚊子”了。）
&#160;
实际上，iPhone OS（iPad也采用iPhone OS）本身是支持多任务的。苹果的的官方解释是CPU，内存的限制以及安全性的考量，所以只支持单任务。但对我而言，这些解释是站不住脚的。举个可能不恰当的比喻，尽管大部分人在大部分时候都不能一心两用，但谁规定了人在看书写文章时就不能同时听音乐，就不能做运动，如果是这样，上帝造人时干脆弄个开关，让人只能做一件事情算了。说道安全性就更不靠谱，上网或运行别人的程序当然有风险，但与我得到的好处相比，我宁愿承担风险，或者说我宁愿自己进行风险评估。更何况App Store不就是用来帮助人们对安装程序进行检查以降低风险的吗？如果这点风险都不愿承受的话，那么人最好不要吃药甚至不用吃东西，因为再好的药物都有可能带来副作用，食物可能包含对人体有害的物质。
&#160;
下图是一些移动平台有关多任务的对比，其优劣大家自己判断：
&#160;
 
&#160;
不过，iPad还会提供一个新的机制可以有限度地支持多任务，那就是支持Dashboard widgets。或许我们可以编写一些运行在后台的widget，谁知道呢？
]]></description>
			<content:encoded><![CDATA[<p>最近很忙再加上新年，所以很久没有更新博客了，抱歉。</p>
<p>&#160;</p>
<p>苹果即将推出的iPad到底具有哪些功能，可谓是众说纷纭。我最为关心的问题是到底iPad是否支持多任务，种种迹象表明答案是否定的。这让许多开发者包括我自己十分失望。缺乏多任务支持使得许多简单的功能都无法实现。记得一位朋友问过我关于在iPhone上实现闹钟功能的问题，这实在是一个简单的程序，可是在没有破解的iPhone上却没办法实现。（准确地说，是无法完美实现。你当然可以写一个运行于前台的闹钟程序，不再运行其它程序，可是它有多实用呢？另外还可以用Push Notification技术，不过这实在有点“大炮打蚊子”了。）</p>
<p>&#160;</p>
<p>实际上，iPhone OS（iPad也采用iPhone OS）本身是支持多任务的。苹果的的官方解释是CPU，内存的限制以及安全性的考量，所以只支持单任务。但对我而言，这些解释是站不住脚的。举个可能不恰当的比喻，尽管大部分人在大部分时候都不能一心两用，但谁规定了人在看书写文章时就不能同时听音乐，就不能做运动，如果是这样，上帝造人时干脆弄个开关，让人只能做一件事情算了。说道安全性就更不靠谱，上网或运行别人的程序当然有风险，但与我得到的好处相比，我宁愿承担风险，或者说我宁愿自己进行风险评估。更何况App Store不就是用来帮助人们对安装程序进行检查以降低风险的吗？如果这点风险都不愿承受的话，那么人最好不要吃药甚至不用吃东西，因为再好的药物都有可能带来副作用，食物可能包含对人体有害的物质。</p>
<p>&#160;</p>
<p>下图是一些移动平台有关多任务的对比，其优劣大家自己判断：</p>
<p>&#160;</p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/03/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.iphone-geek.cn/wp-content/uploads/2010/03/image_thumb.png" width="477" height="295" /></a> </p>
<p>&#160;</p>
<p>不过，iPad还会提供一个新的机制可以有限度地支持多任务，那就是支持Dashboard widgets。或许我们可以编写一些运行在后台的widget，谁知道呢？</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipadiphone%e4%b8%8e%e5%a4%9a%e4%bb%bb%e5%8a%a1/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>新春快乐！</title>
		<link>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/%e6%96%b0%e6%98%a5%e5%bf%ab%e4%b9%90%ef%bc%81</link>
		<comments>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/%e6%96%b0%e6%98%a5%e5%bf%ab%e4%b9%90%ef%bc%81#comments</comments>
		<pubDate>Sat, 13 Feb 2010 05:21:30 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[闲谈]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=898</guid>
		<description><![CDATA[新年将近，祝各位新春快乐，身体健康，万事如意！


]]></description>
			<content:encoded><![CDATA[<p>新年将近，祝各位新春快乐，身体健康，万事如意！</p>
<p><br class="spacer_" /></p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2010/02/2008520211942659_2.jpg"><img class="alignnone size-full wp-image-902" title="2008520211942659_2" src="http://www.iphone-geek.cn/wp-content/uploads/2010/02/2008520211942659_2.jpg" alt="2008520211942659_2" width="591" height="532" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/%e6%96%b0%e6%98%a5%e5%bf%ab%e4%b9%90%ef%bc%81/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone不是Mac Pro</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro#comments</comments>
		<pubDate>Tue, 09 Feb 2010 05:21:03 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[提示与技巧]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=359</guid>
		<description><![CDATA[本文是关于通过Objective C++的强大功能提高iPhone程序的性能。通过讨论现实世界中Savoy的Spots应用程序遇到的问题，本文展示了通过3个步骤对程序进行优化使其顺利运行的过程。




使用Objective C++提高iPhone应用程序的性能

我十分喜爱软件开发的一个原因是总是会遇到这样那样的问题，而总能找到相应的解决方法。在开发Spots时，我多次遇到了UI设计的问题。为  iPhone设计一个精简的用户界面是不容易的。比如，我应该提供一个提供者过滤器（指Hotspot）按钮或将其放在Settings.app中？关于这个问题，我至少改变了二十次主意？

本文不是关于用户界面设计而是有关编程与性能。本文并不是针对用户界面而是有关编程和性能。一个最大的难题是地图的绘制（屏幕下方的长方形）。经过几种方法的试用，我发现在绘制230，000个点时，只有使用OpenGL以及大量的旁门左道才能使绘图的性能勉强被接受。根据放大的级别以及可见点点数量，我最后使用了三种不同的技术。由于我需要地图交互动作（拖动和缩放）尽可能地平滑，理想情况下为60HZ，性能是最为重要的问题。



本文中我将分享一些能提高性能的技术。虽然它们都很简单和直接，但因为在Cocoa中很少见，所以我还是花了不少时间。例如，尽管C++和Objective  C可以非常高效地混合使用，但我在Cocoa中并没有见到许多C++。当你的目标是高性能时，Objective  C++是纯Cocoa的很好的扩展。而在iPhone上，性能是应该首先需要考虑到因素。

难题

对于分布在一个矩形区域包括230，000个热点位置的地图（麦卡托投影的世界地图 the world map in mercator  projection），首先必须清楚当前地图矩形区域中有多少个可见点，因为此数值可以决定使用何种绘图技术。指标值必须归一，因此整个地图覆盖了一个{{0.0,  1.0}, {0.0, 1.0}}的矩形区域。通常情况下，程序使用的地图矩形是很小的：通常小于整个地图宽度和高度的百分之二。




但是我怎样有效地在数据库成千上万的点中找到可见点的数量？

我准备了一个XCode项目，它包括了这里讨论的所有代码。此示例项目并未包括了所有点的原始数据库。它仅包含了一些世界地图上的随机数据。虽然与真实情况有所区别，但它们的处理方法与我收集的原始数据的大同小异。

第一种方法: 普通Cocoa方法

第一种方法十分简单而且并没有采用十分高效的方法。使用Object C对象（@class  Spot）来表示位置，它们以NSArrary的形式被保存在一个数据库对象中（@class SpotsDB1）。
@interface Spot : NSObject {
    CGPoint _position;
}
@property (nonatomic) CGPoint position;
@end

@interface SpotsDB1 : NSObject {
    NSArray* _spots;
}
- (NSUInteger)countSpotsInRect:(CGRect)rect;
@end

为进行一个指定CGRect内地位置计数，数据库对象简单地循环整个数组并检查各位置。

NSUInteger count = 0;
 for (Spot* spot in _spots) {
 [...]]]></description>
			<content:encoded><![CDATA[<p>本文是关于通过Objective C++的强大功能提高iPhone程序的性能。通过讨论现实世界中Savoy的<a href="http://www.savoysoftware.com/spots/">Spots</a>应用程序遇到的问题，本文展示了通过3个步骤对程序进行优化使其顺利运行的过程。</p>
<p><br class="spacer_" /></p>
<p><a href="http://www.savoysoftware.com/spots/"><img title="spots-icon-big" src="http://savoysoftware.com/blog/wp-content/uploads/2008/12/spots-icon-big.png" alt="Spots" width="165" height="165" /></a></p>
<p><br class="spacer_" /></p>
<p><img title="More..." src="../wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span id="more-359"></span></p>
<h3><strong>使用Objective C++提高iPhone应用程序的性能</strong></h3>
<p><br class="spacer_" /></p>
<p>我十分喜爱软件开发的一个原因是总是会遇到这样那样的问题，而总能找到相应的解决方法。在开发Spots时，我多次遇到了UI设计的问题。为  iPhone设计一个精简的用户界面是不容易的。比如，我应该提供一个提供者过滤器（指Hotspot）按钮或将其放在Settings.app中？关于这个问题，我至少改变了二十次主意？</p>
<p><br class="spacer_" /></p>
<p>本文不是关于用户界面设计而是有关编程与性能。本文并不是针对用户界面而是有关编程和性能。一个最大的难题是地图的绘制（屏幕下方的长方形）。经过几种方法的试用，我发现在绘制230，000个点时，只有使用OpenGL以及大量的旁门左道才能使绘图的性能勉强被接受。根据放大的级别以及可见点点数量，我最后使用了三种不同的技术。由于我需要地图交互动作（拖动和缩放）尽可能地平滑，理想情况下为60HZ，性能是最为重要的问题。</p>
<p><br class="spacer_" /></p>
<p><img title="map_spots" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/map_spots.png" alt="map_spots" width="320" height="211" /></p>
<p><br class="spacer_" /></p>
<p>本文中我将分享一些能提高性能的技术。虽然它们都很简单和直接，但因为在Cocoa中很少见，所以我还是花了不少时间。例如，尽管C++和Objective  C可以非常高效地混合使用，但我在Cocoa中并没有见到许多C++。当你的目标是高性能时，Objective  C++是纯Cocoa的很好的扩展。而在iPhone上，性能是应该首先需要考虑到因素。</p>
<p><br class="spacer_" /></p>
<h4><strong>难题</strong></h4>
<p><br class="spacer_" /></p>
<p>对于分布在一个矩形区域包括230，000个热点位置的地图（麦卡托投影的世界地图 the world map in mercator  projection），首先必须清楚当前地图矩形区域中有多少个可见点，因为此数值可以决定使用何种绘图技术。指标值必须归一，因此整个地图覆盖了一个{{0.0,  1.0}, {0.0, 1.0}}的矩形区域。通常情况下，程序使用的地图矩形是很小的：通常小于整个地图宽度和高度的百分之二。</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><img title="map" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/map.png" alt="map" width="453" height="343" /></p>
<p><br class="spacer_" /></p>
<p>但是我怎样有效地在数据库成千上万的点中找到可见点的数量？</p>
<p><br class="spacer_" /></p>
<p>我准备了一个<a href="http://savoysoftware.com/blog/wp-content/uploads/2009/01/spotsdb.zip">XCode项目</a>，它包括了这里讨论的所有代码。此示例项目并未包括了所有点的原始数据库。它仅包含了一些世界地图上的随机数据。虽然与真实情况有所区别，但它们的处理方法与我收集的原始数据的大同小异。</p>
<p><br class="spacer_" /></p>
<h5>第一种方法: 普通Cocoa方法</h5>
<p><br class="spacer_" /></p>
<p>第一种方法十分简单而且并没有采用十分高效的方法。使用Object C对象（@class  Spot）来表示位置，它们以NSArrary的形式被保存在一个数据库对象中（@class SpotsDB1）。</p>
<pre>@interface Spot : NSObject {
    CGPoint _position;
}
@property (nonatomic) CGPoint position;
@end

@interface SpotsDB1 : NSObject {
    NSArray* _spots;
}
- (NSUInteger)countSpotsInRect:(CGRect)rect;
@end</pre>
<p><br class="spacer_" /></p>
<p>为进行一个指定CGRect内地位置计数，数据库对象简单地循环整个数组并检查各位置。</p>
<p><br class="spacer_" /></p>
<p>NSUInteger count = 0;<br />
 for (Spot* spot in _spots) {<br />
 if  (CGRectContainsPoint(aRect, spot.position))<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>使用上述代码，在总数为230，000个点的区域上的任意一个{0.02,  0.02}矩形内进行计数大概需要250毫秒。太糟糕了，如果你的目标是刷新率60Hz，那么你只有16  ms绘制一帧。使得此方案过慢的原因不仅在于其缺乏聪明的算法，而且在循环中浪费了许多时间在调用了几个函数上。另一个对性能产生负面影响的因素是位置被保存在NSArray中的对象，这是由于对象占用了大量的内存以及数组指针的非直接性导致了处理器时间的增加。</p>
<p><br class="spacer_" /></p>
<h5>第二种方法: 简单优化</h5>
<p><br class="spacer_" /></p>
<p>为使同样的方案运行得更快，我们只需简单地将位置存储与一个更为紧凑的数据结构中：一个CGPoint结构的标准C数组。为使用方便，我们将C数组保存在一个NSMutableData  对象中。</p>
<p><br class="spacer_" /></p>
<p>_spotCount = [spots count];<br />
 _spotsData = [[NSMutableData alloc]  init];<br />
 for (Spot* spot in spots) {<br />
 CGPoint p = spot.position;<br />
 [data appendBytes:&amp;p length:sizeof(CGPoint)];<br />
 }</p>
<p><br class="spacer_" /></p>
<p>消除了循环内函数调用的负面影响，我们使得性能有四倍的提升：</p>
<p><br class="spacer_" /></p>
<p>CGFloat xMin = CGRectGetMinX(aRect);<br />
 CGFloat yMin =  CGRectGetMinY(aRect);<br />
 CGFloat xMax = CGRectGetMaxX(aRect);<br />
 CGFloat yMax =  CGRectGetMaxY(aRect);</p>
<p>CGPoint* begin = (CGPoint*)[_spotsData  bytes];<br />
 CGPoint* end = begin + _spotCount;</p>
<p>NSUInteger count =  0;<br />
 for (CGPoint* i = begin; i != end; ++i) {<br />
 if (i-&gt;x &gt; xMin  &amp;&amp; i-&gt;y &gt; yMin &amp;&amp; i-&gt;x &lt; xMax &amp;&amp; i-&gt;y  &lt; yMax)<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>在没有改变基本算法的基础上，点计数的计算现在只需55毫秒，这大概比原来方法快了四倍。另一个好处是现在使用的内存是原来版本的一半。</p>
<h5>第三种方法：算法优化</h5>
<p><br class="spacer_" /></p>
<p>当然，还有许多聪明的方法来优化平面地图点的查询。例如，你可以使用四边形树来保存这些点。在本例中我使用了一种比较简单的解决方案，所以没有涉及数据存储的方式。我使用了C++的内置功能所以甚至不需要写任何代码来处理数据的存储。</p>
<p><br class="spacer_" /></p>
<p><img title="sorted" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/sorted.png" alt="sorted" width="355" height="343" /></p>
<p><br class="spacer_" /></p>
<p>我的设想是将数组中的位置从左至右分类。这样做的好处是确定指定正方形的左右边界十分快速（见下图）。当数组中边界已知时，仅需要检查边界间的点。</p>
<p><br class="spacer_" /></p>
<p><img title="sorted2" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/sorted2.png" alt="sorted2" width="355" height="343" /></p>
<p><br class="spacer_" /></p>
<p>所以此算法是有关快速寻找边界的。我们使用的是<a href="http://en.wikipedia.org/wiki/Binary_search">二进制搜索</a>，  它适用于已排序的数组。它并不检查每个值以找到匹配的位置，而是直接跳到数组的中点，检查其值是小于还是大于给点值，然后跳到剩余部分的中心点，重复以上步骤。使用这种方法，二进制搜索需要  log2(n)的时间来查找最佳元素。对于一个拥有230，000个位置的数组，只需22次搜索！回到代码，我们发现上述算法的实现是很简单的。当然，我们必须为数据库排序：</p>
<pre>// comparison function for array sorting
NSInteger leftToRight(Spot* a, Spot* b, void* context) {
    CGFloat xa = a.position.x;
    CGFloat xb = b.position.x;
    if (xa &lt; xb)
        return NSOrderedAscending;
    return xa &gt; xb ? NSOrderedDescending : NSOrderedSame;
}

...

spots = [spots sortedArrayUsingFunction:leftToRight context:NULL];</pre>
<p><br class="spacer_" /></p>
<p>现在是有趣的部分：使用C++进行二进制搜索。我们使用了#include &lt;algorithm&gt;中的库函数  std::lower_bound。它需要一个起点，终点，要查找的值以及比较函数。它返回比较为false的第一个值。起点和终点可以是简单的<span style="font-family: 微软雅黑;">指向数组的C指针。</span></p>
<p><br class="spacer_" /></p>
<p>#include &lt;algorithm&gt;<br />
 &#8230;</p>
<p>bool cmpX(const  CGPoint&amp; a, const CGPoint&amp; b) {<br />
 return a.x &lt;  b.x;<br />
 }<br />
 &#8230;</p>
<p>CGFloat yMin = CGRectGetMinY(aRect);<br />
 CGFloat yMax =  CGRectGetMaxY(aRect);</p>
<p>CGPoint* begin = (CGPoint*)[_spotsData  bytes];<br />
 CGPoint* end = begin + _spotCount;</p>
<p>CGPoint leftMargin =  aRect.origin;<br />
 CGPoint rightMargin;<br />
 rightMargin.x =  CGRectGetMaxX(aRect);</p>
<p>CGPoint* left  = std::lower_bound(begin, end,  leftMargin, cmpX);<br />
 CGPoint* right = std::lower_bound(left, end, rightMargin,  cmpX);</p>
<p>NSUInteger count = 0;<br />
 for (CGPoint* i = left; i != right; ++i)  {<br />
 if (i-&gt;y &gt; yMin &amp;&amp; i-&gt;y &lt; yMax)<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>注意第二个二进制搜索，它仅从左边界而不是整个数组查找右边界。另一个优化是从循环中移除X-轴的检查，这是因为已经通过指定边界完成了这部分工作。</p>
<p><br class="spacer_" /></p>
<p>通过这些优化，只需要1毫秒来对长方形进行计数。这是第一个版本的200倍。</p>
<h5>结果</h5>
<p><br class="spacer_" /></p>
<p>下面是运行在三种不同设备上的<a href="http://savoysoftware.com/blog/wp-content/uploads/2009/01/spotsdb.zip">示例项目</a>的输出。如果你需要运行在你自己的设备上，你只需将目标设定中将代码签名标识符改为自己的。如果你不希望用在通用标识符的程序上，你还需要更改Info.plist中的包标识符（Bundle  Identifier）。</p>
<p><br class="spacer_" /></p>
<p>iPhone 3G：</p>
<pre>SpotsDB1 needed 3.2 seconds to count spots in 13 rects
that's 244.423 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 55 rects
that's 55.230 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 2988 rects
that's 1.004 ms per rect</pre>
<p>第二代iPod Touch：</p>
<pre>SpotsDB1 needed 3.1 seconds to count spots in 16 rects
that's 194.756 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 65 rects
that's 46.450 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 3399 rects
that's 0.883 ms per rect</pre>
<p>运行在Mac Pro之上的模拟器：</p>
<pre>SpotsDB1 needed 3.0 seconds to count spots in 687 rects
that's 4.372 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 2687 rects
that's 1.117 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 187276 rects
that's 0.016 ms per rect</pre>
<h5>结论</h5>
<p><br class="spacer_" /></p>
<p>观察结果我们可以看出在桌面电脑和iPhone上性能有显著的区别。有一个金科玉律是：在Mac上只需一秒的操作在iPhone上要一分钟。或者有一个更悲观的说法：Mac上60Hz的刷新率在iPhone上每秒钟只能更新一次。</p>
<p><br class="spacer_" /></p>
<p>所以显而易见在iPhone上进行优化是完全必须的。本文中我展示了几种方法来减小Object  C的开销以及怎样使用C++来获得最大的性能。当然找到性能的瓶颈并转而使用数据结构使代码性能提升并不总是很容易的事情。但是在设计一个使用大量数据的程序时，绝对有必要考虑使用非Cocoa的方法。</p>
<h6>原文见：<a href="http://www.savoysoftware.com/blog/?p=114">My iPhone is not a  Mac Pro</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone是个“大嘴巴”</title>
		<link>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/iphone%e6%98%af%e4%b8%aa%e2%80%9c%e5%a4%a7%e5%98%b4%e5%b7%b4%e2%80%9d</link>
		<comments>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/iphone%e6%98%af%e4%b8%aa%e2%80%9c%e5%a4%a7%e5%98%b4%e5%b7%b4%e2%80%9d#comments</comments>
		<pubDate>Mon, 08 Feb 2010 03:11:51 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[闲谈]]></category>
		<category><![CDATA[安全]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=877</guid>
		<description><![CDATA[
TaranFx上有一篇文章介绍了一个名为SpyPhone的新的开源程序，它将当前iPhone SDK的“信息脆弱点”都完全曝光。下面是该文章的链接：

SpyPhone程序从所有iPhone数据

大家可能都听说过越狱iPhone用户可能遇到的一些问题。没有SDK的限制，许多用户的手机都被恶意程序通过默认的root密码劫持了。不像我们听说过的其它一些程序，SpyPhone仅利用公共API获取它显示的信息。它显示了：

Email账户
Wi-Fi 网络
电话使用信息及历史信息
位置信息
Safari 搜索
YouTube 搜索，历史和书签
照片
地址簿数据
键盘缓存


在这里我们的目的并不是向大家大声抱怨安全，隐私问题，而是要看看到底该程序是怎样做的。SpyPhone的源代码可以在 git hub 下载，你可以自己看看到底它是怎样完成这些工作的。快速浏览了一下它的源代码，我们发现iPhone像 Macintosh电脑一样都包括一些文件夹，比如“Applications”, “Library”, “Root”等等。如果你安装了SDK，那么你可以在iPhone模拟器上找到这些文件夹。它们在：


~/Library/Application Support/iPhone Simulator/User



这就是iPhone保存所有数据的地方。再看下SpyPhone的源代码，它的秘密就是利用这些文件夹和它们包含的文件。如果你再进一步，你会在iPhone模拟器的文件夹下发现：


~/Library/Application Support/iPhone Simulator/User/Library/Preferences/



这里有许多 com.apple.SOMETHING.plist 文件。这些文件就是SpyPhone获取大部分数据的源头（其它数据可以通过SDK的其他部分，如地址簿访问，照片服务等）。它使用下面代码获取数据：



NSString *path = @"/Library/Preferences/SystemConfiguration/com.apple.wifi.plist";
 
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
 
if(!dict) return;
 
NSArray *a = [dict valueForKey:@"List of known networks"];
 
if(!a) return;


 
NSString *path = @”/Library/Preferences/SystemConfiguration/com.apple.wifi.plist”;
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
if(!dict) return;
NSArray *a = [dict valueForKey:@"List of known networks"];

if(!a) return;


上面的代码获取程序运行其上的电话的网络信息，它包括在一个数组中。尽管有些担忧，但我认为它还并不是罪恶滔天。首先我知道Apple会拒绝这样的程序出现在App Store上。Apple对SDK可谓是了如指掌，所有它可以叫停所有的滥用其SDK的程序。

但是该程序为神秘的App Store批准过程提出了一个挑战。令人难以置信的是获取进入世界上发展最快的软件市场的入场卷是如此的神秘。像SpyPhone这样截取“敏感”信息的代码随时可能发生而用户并不知情。虽然Apple可以监视对PLIST的访问，但我很容易就可以想像到某些程序具有绕过Apple检查的能力直到某天我们知道它出现在App Store上。

例如，我有一个在线 XML 文档指定是否要运行截取用户信息的方法，在App [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://icodeblog.com/wp-content/uploads/2009/12/newton-virus-objectsq.jpg"><img title="newton-virus-objectsq" src="http://icodeblog.com/wp-content/uploads/2009/12/newton-virus-objectsq-150x150.jpg" alt="newton-virus-objectsq" width="150" height="150" /></a></p>
<p>TaranFx上有一篇文章介绍了一个名为SpyPhone的新的开源程序，它将当前iPhone SDK的“信息脆弱点”都完全曝光。下面是该文章的链接：</p>
<p><br class="spacer_" /></p>
<p><a title="SpyPhone App Steals Personal Data from ALL iPhones" href="http://www.taranfx.com/blog/spyphone-app-steals-personal-data-from-all-iphones" target="_blank">SpyPhone程序从所有iPhone数据</a></p>
<p><br class="spacer_" /></p>
<p>大家可能都听说过越狱iPhone用户可能遇到的一些问题。没有SDK的限制，许多用户的手机都被恶意程序通过默认的root密码<a title="Jailbroken iPhones Being Held Hostage" href="http://arstechnica.com/apple/news/2009/11/dutch-hacker-holds-jailbroken-iphones-hostage-for-5.ars">劫持</a>了。不像我们听说过的其它一些程序，SpyPhone仅利用公共API获取它显示的信息。它显示了：</p>
<ol>
<li>Email账户</li>
<li>Wi-Fi 网络</li>
<li>电话使用信息及历史信息</li>
<li>位置信息</li>
<li>Safari 搜索</li>
<li>YouTube 搜索，历史和书签</li>
<li>照片</li>
<li>地址簿数据</li>
<li>键盘缓存</li>
</ol>
<p><br class="spacer_" /></p>
<p>在这里我们的目的并不是向大家大声抱怨安全，隐私问题，而是要看看到底该程序是怎样做的。SpyPhone的源代码可以在 <a title="SpyPhone's Git Hub" href="http://github.com/nst/spyphone/">git hub</a> 下载，你可以自己看看到底它是怎样完成这些工作的。快速浏览了一下它的源代码，我们发现iPhone像 Macintosh电脑一样都包括一些文件夹，比如“Applications”, “Library”, “Root”等等。如果你安装了SDK，那么你可以在iPhone模拟器上找到这些文件夹。它们在：</p>
<div>
<div>
<pre style="font-family: monospace;">~<span style="color: #002200;">/</span>Library<span style="color: #002200;">/</span>Application Support<span style="color: #002200;">/</span>iPhone Simulator<span style="color: #002200;">/</span>User</pre>
</div>
</div>
<p><br class="spacer_" /></p>
<p>这就是iPhone保存所有数据的地方。再看下SpyPhone的源代码，它的秘密就是利用这些文件夹和它们包含的文件。如果你再进一步，你会在iPhone模拟器的文件夹下发现：</p>
<div>
<div>
<pre style="font-family: monospace;">~<span style="color: #002200;">/</span>Library<span style="color: #002200;">/</span>Application Support<span style="color: #002200;">/</span>iPhone Simulator<span style="color: #002200;">/</span>User<span style="color: #002200;">/</span>Library<span style="color: #002200;">/</span>Preferences<span style="color: #002200;">/</span></pre>
</div>
</div>
<p><br class="spacer_" /></p>
<p>这里有许多 com.apple.SOMETHING.plist 文件。这些文件就是SpyPhone获取大部分数据的源头（其它数据可以通过SDK的其他部分，如地址簿访问，照片服务等）。它使用下面代码获取数据：</p>
<div>
<div>
<pre style="font-family: monospace;"><span style="color: #400080;">
NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">"/Library/Preferences/SystemConfiguration/com.apple.wifi.plist"</span>;
 
<span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>dict <span style="color: #002200;">=</span> <span style="color: #002200;">[</span><span style="color: #400080;">NSDictionary</span> dictionaryWithContentsOfFile<span style="color: #002200;">:</span>path<span style="color: #002200;">]</span>;
 
<span style="color: #a61390;">if</span><span style="color: #002200;">(</span><span style="color: #002200;">!</span>dict<span style="color: #002200;">)</span> <span style="color: #a61390;">return</span>;
 
<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>a <span style="color: #002200;">=</span> <span style="color: #002200;">[</span>dict valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">"List of known networks"</span><span style="color: #002200;">]</span>;
 
<span style="color: #a61390;">if</span><span style="color: #002200;">(</span><span style="color: #002200;">!</span>a<span style="color: #002200;">)</span> <span style="color: #a61390;">return</span>;</pre>
</div>
</div>
<p><span style="color: #000000;"> </span></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 470px; width: 1px; height: 1px;">NSString *path = @”/Library/Preferences/SystemConfiguration/com.apple.wifi.plist”;</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 470px; width: 1px; height: 1px;">NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 470px; width: 1px; height: 1px;">if(!dict) return;</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 470px; width: 1px; height: 1px;">NSArray *a = [dict valueForKey:@"List of known networks"];</div>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 470px; width: 1px; height: 1px;">
<p>if(!a) return;</p>
</div>
<p><br class="spacer_" /></p>
<p>上面的代码获取程序运行其上的电话的网络信息，它包括在一个数组中。尽管有些担忧，但我认为它还并不是罪恶滔天。首先我知道Apple会拒绝这样的程序出现在App Store上。Apple对SDK可谓是了如指掌，所有它可以叫停所有的滥用其SDK的程序。</p>
<p><br class="spacer_" /></p>
<p>但是该程序为神秘的App Store批准过程提出了一个挑战。令人难以置信的是获取进入世界上发展最快的软件市场的入场卷是如此的神秘。像SpyPhone这样截取“敏感”信息的代码随时可能发生而用户并不知情。虽然Apple可以监视对PLIST的访问，但我很容易就可以想像到某些程序具有绕过Apple检查的能力直到某天我们知道它出现在App Store上。</p>
<p><br class="spacer_" /></p>
<p>例如，我有一个在线 XML 文档指定是否要运行截取用户信息的方法，在App Store审核期间将其设为NO而在获取批准后设为YES，开始收集用户数据。所以尽管Apple有很好的方法来防止恶意程序，但我确信有许多方法可以逃过Apple的检查。所以我产生了最后一个问题，大家是否宁愿程序不具有使用这些信息的能力？没有照片，没有地址簿，没有wifi侦测，程序mail限制。大部分这些使iPhone变得精彩的程序都被“安全隐患”包围着。大家怎么看？是否Apple应该至少关闭系统PLIST的访问？</p>
<p><br class="spacer_" /></p>
<h5>原文见：<a title="Permanent Link to The iPhone is Bad at Keeping Secrets" rel="bookmark" href="http://icodeblog.com/2009/12/05/the-iphone-is-bad-at-keeping-secrets/">The iPhone is Bad at Keeping Secrets </a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/iphone%e6%98%af%e4%b8%aa%e2%80%9c%e5%a4%a7%e5%98%b4%e5%b7%b4%e2%80%9d/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>使用UIImagePickerController从iPhone照片库或照相机获取图像</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bd%bf%e7%94%a8uiimagepickercontroller%e4%bb%8eiphone%e7%85%a7%e7%89%87%e5%ba%93%e6%88%96%e7%85%a7%e7%9b%b8%e6%9c%ba%e8%8e%b7%e5%8f%96%e5%9b%be%e5%83%8f</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bd%bf%e7%94%a8uiimagepickercontroller%e4%bb%8eiphone%e7%85%a7%e7%89%87%e5%ba%93%e6%88%96%e7%85%a7%e7%9b%b8%e6%9c%ba%e8%8e%b7%e5%8f%96%e5%9b%be%e5%83%8f#comments</comments>
		<pubDate>Fri, 05 Feb 2010 10:16:10 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[图形图像]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[UIImagePckerController]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=873</guid>
		<description><![CDATA[本文讲述使用3.0的方法怎样从iPhone的照片库或照相机获取图像。

我们将创建一个应用程序从图片库或照相机获取图像并显示与屏幕之上。下面是截图：



1. 创建一个新的 View Based 程序

我将其命名为 photoApp
 
2. 创建IBOutlet 和 IBAction

打开 photoAppViewController.h 加入下面代码：


#import 
 
@interface PhotoAppViewController : UIViewController
    &#60; UIImagePickerControllerDelegate, UINavigationControllerDelegate &#62; {
	UIImageView * imageView;
	UIButton * choosePhotoBtn;
	UIButton * takePhotoBtn;
}
 
@property (nonatomic, retain) IBOutlet UIImageView * imageView;
@property (nonatomic, retain) IBOutlet UIButton * choosePhotoBtn;
@property (nonatomic, retain) IBOutlet UIButton * takePhotoBtn;
 
-(IBAction) getPhoto:(id) sender;
 
@end



注意我们实现了 UIImagePickerControlDelegate 和 UINavigationControllerDelegate 协议。为了与图像拾取器正确地接口，这两者都是必需的。其余部分应该很简单。我们设定了要使用按钮的IBOutlet以及按下这些按钮时被调用的IBAction。getPhoto方法将显示图像拾取器。
 
3. 创建接口

在Interface Builder中打开photoAppViewController.xib [...]]]></description>
			<content:encoded><![CDATA[<p>本文讲述使用3.0的方法怎样从iPhone的照片库或照相机获取图像。</p>
<p><br class="spacer_" /></p>
<p>我们将创建一个应用程序从图片库或照相机获取图像并显示与屏幕之上。下面是截图：</p>
<p><br class="spacer_" /></p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/07/photo-21.jpg"><img title="photo 2" src="http://icodeblog.com/wp-content/uploads/2009/07/photo-21.jpg" alt="photo 2" width="320" height="480" /></a></p>
<p><span id="more-873"></span></p>
<h3>1. 创建一个新的 View Based 程序</h3>
<p><br class="spacer_" /></p>
<p>我将其命名为 photoApp</p>
<h2> </h2>
<h2>2. 创建IBOutlet 和 IBAction</h2>
<p><br class="spacer_" /></p>
<p>打开 <strong>photoAppViewController.h </strong>加入下面代码：</p>
<div>
<div>
<pre style="font-family: monospace;"><span style="color: #6e371a;">#import </span>
 
<span style="color: #a61390;">@interface</span> PhotoAppViewController <span style="color: #002200;">:</span> UIViewController
    &lt; UIImagePickerControllerDelegate, UINavigationControllerDelegate &gt; <span style="color: #002200;">{</span>
	UIImageView <span style="color: #002200;">*</span> imageView;
	UIButton <span style="color: #002200;">*</span> choosePhotoBtn;
	UIButton <span style="color: #002200;">*</span> takePhotoBtn;
<span style="color: #002200;">}</span>
 
<span style="color: #a61390;">@property</span> <span style="color: #002200;">(</span>nonatomic, retain<span style="color: #002200;">)</span> IBOutlet UIImageView <span style="color: #002200;">*</span> imageView;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">(</span>nonatomic, retain<span style="color: #002200;">)</span> IBOutlet UIButton <span style="color: #002200;">*</span> choosePhotoBtn;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">(</span>nonatomic, retain<span style="color: #002200;">)</span> IBOutlet UIButton <span style="color: #002200;">*</span> takePhotoBtn;
 
<span style="color: #002200;">-</span><span style="color: #002200;">(</span>IBAction<span style="color: #002200;">)</span> getPhoto<span style="color: #002200;">:</span><span style="color: #002200;">(</span><span style="color: #a61390;">id</span><span style="color: #002200;">)</span> sender;
 
<span style="color: #a61390;">@end</span></pre>
</div>
</div>
<p><br class="spacer_" /></p>
<p>注意我们实现了 <strong>UIImagePickerControlDelegate</strong> 和<strong> UINavigationControllerDelegate </strong>协议。为了与图像拾取器正确地接口，这两者都是必需的。其余部分应该很简单。我们设定了要使用按钮的IBOutlet以及按下这些按钮时被调用的IBAction。getPhoto方法将显示图像拾取器。</p>
<h2> </h2>
<h2>3. 创建接口</h2>
<p><br class="spacer_" /></p>
<p>在Interface Builder中打开photoAppViewController.xib 并遵循下面步骤：</p>
<ol>
<li>将 UIImageView 拖入main view</li>
<li>在Attribute inspector（属性检查器）中将 UIImageView 的 <strong>Mode （模式）</strong> 设置为 <strong>Aspect Fit</strong></li>
<li>将 UIButton 拖入view 中并命名为<strong> Choose Photo （选取照片）</strong></li>
<li>将另一个 UIButton 拖入view 中并命名为 <strong>Take Photo （照相）</strong></li>
</ol>
<p><br class="spacer_" /></p>
<p>接口看上去像这样：</p>
<p><br class="spacer_" /></p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/07/screenshot_013.png"><img title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/07/screenshot_013.png" alt="screenshot_01" width="320" height="502" /></a></p>
<h2>4. 连接IBoutlets 和 IBAction</h2>
<ol>
<li>将 choosePhotoBtn 连接到名为 <strong>Choose Photo </strong>的UIButton上</li>
<li>将 imageView 连接到 UIImageView</li>
<li>将各按钮的<strong>Touch Up Inside</strong> 回调连接到 <strong>getPhoto</strong>方法</li>
</ol>
<p><br class="spacer_" /></p>
<p>当你按下 <strong>File’s Owner</strong> 时，Connection Inspector （连接检查器）应该像这样：</p>
<div id="in_post_ad_middle_1" style="margin: 5px; padding: 0px;">
<div id="ad-article"><noscript></noscript><!-- END NetShelter Ad Tag for TGDaily second rectangle 300x250,336x280,300x600 --></div>
</div>
<p><br class="spacer_" /></p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/07/screenshot_014.png"><img title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/07/screenshot_014.png" alt="screenshot_01" width="289" height="213" /></a></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p>关闭 Interface Builder</p>
<p><br class="spacer_" /></p>
<h2>5. 实现 getPhoto 方法</h2>
<p><br class="spacer_" /></p>
<p>打开 <strong>PhotoAppViewController.m </strong>a并nd add the following code:</p>
<div>
<div>
<pre style="font-family: monospace;"><span style="color: #a61390;">@synthesize</span> imageView,choosePhotoBtn, takePhotoBtn;
 
<span style="color: #002200;">-</span><span style="color: #002200;">(</span>IBAction<span style="color: #002200;">)</span> getPhoto<span style="color: #002200;">:</span><span style="color: #002200;">(</span><span style="color: #a61390;">id</span><span style="color: #002200;">)</span> sender <span style="color: #002200;">{</span>
	UIImagePickerController <span style="color: #002200;">*</span> picker <span style="color: #002200;">=</span> <span style="color: #002200;">[</span><span style="color: #002200;">[</span>UIImagePickerController alloc<span style="color: #002200;">]</span> init<span style="color: #002200;">]</span>;
	picker.delegate <span style="color: #002200;">=</span> self;
 
	<span style="color: #a61390;">if</span><span style="color: #002200;">(</span><span style="color: #002200;">(</span>UIButton <span style="color: #002200;">*</span><span style="color: #002200;">)</span> sender <span style="color: #002200;">==</span> choosePhotoBtn<span style="color: #002200;">)</span> <span style="color: #002200;">{</span>
		picker.sourceType <span style="color: #002200;">=</span> UIImagePickerControllerSourceTypeSavedPhotosAlbum;
	<span style="color: #002200;">}</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">{</span>
		picker.sourceType <span style="color: #002200;">=</span> UIImagePickerControllerSourceTypeCamera;
	<span style="color: #002200;">}</span>
 
	<span style="color: #002200;">[</span>self presentModalViewController<span style="color: #002200;">:</span>picker animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">]</span>;
<span style="color: #002200;">}</span></pre>
</div>
</div>
<p><br class="spacer_" /></p>
<p>首先创建一个新的UIImagePickerController对象。它是一个视图控制器，可以按任意视图控制器方式正常显示出来（显示于导航视图，加载于表格视图，呈现为模型视图控制器等）。然后，设置代理为我们的视图控制器。它表示当用户选取照片时，拾取器将调用类中的某个方法。</p>
<p><br class="spacer_" /></p>
<p>接着，确定哪个按钮被按下。由于两个按钮都连接到此方法上，我们需要使用 == 来确定到底哪个被按下。到底是显示照相机图片还是显示照片库图片是由拾取器的一个属性决定的。看看代码你就会很清楚。</p>
<p><br class="spacer_" /></p>
<p>最后，调用presentModalViewController。它将使拾取器以动画的形式从屏幕底向上移动，切换到视图。根据按下的按钮的不同，你将看到下面图像：</p>
<p><br class="spacer_" /></p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/07/photo-3.jpg"><img title="photo 3" src="http://icodeblog.com/wp-content/uploads/2009/07/photo-3.jpg" alt="photo 3" width="320" height="480" /></a><a href="http://icodeblog.com/wp-content/uploads/2009/07/photo.jpg"><img title="photo" src="http://icodeblog.com/wp-content/uploads/2009/07/photo.jpg" alt="photo" width="320" height="480" /></a></p>
<h2> </h2>
<h2>6. 显示选择的图像</h2>
<p><br class="spacer_" /></p>
<p>一旦选择了照片， ImagePicker 将回调 <strong>didFinishPickingMediaWithInfo。</strong>在<strong>PhotoAppViewController.m </strong>文件中进入下列代码：<strong> </strong></p>
<div>
<div>
<pre style="font-family: monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">(</span><span style="color: #a61390;">void</span><span style="color: #002200;">)</span>imagePickerController<span style="color: #002200;">:</span><span style="color: #002200;">(</span>UIImagePickerController <span style="color: #002200;">*</span><span style="color: #002200;">)</span>picker
    didFinishPickingMediaWithInfo<span style="color: #002200;">:</span><span style="color: #002200;">(</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">)</span>info <span style="color: #002200;">{</span>
	<span style="color: #002200;">[</span>picker dismissModalViewControllerAnimated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">]</span>;
	imageView.image <span style="color: #002200;">=</span> <span style="color: #002200;">[</span>info objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">"UIImagePickerControllerOriginalImage"</span><span style="color: #002200;">]</span>;
<span style="color: #002200;">}</span></pre>
<pre style="font-family: monospace;"><span style="color: #002200;"> </span> </pre>
</div>
</div>
<p>第一行代码隐藏拾取器。随后将图像视图的<strong>image</strong> 属性设置为返回的图像。拾取器返回一个NSDictionary对象。这是由于 <a href="http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html#//apple_ref/doc/c_ref/UIImagePickerControllerMediaType">UIImagePickerControllerMediaType</a> 将指示返回的是视频还是图像。</p>
<p><br class="spacer_" /></p>
<p><a href="http://icodeblog.com/wp-content/uploads/2009/07/PhotoApp.zip">iPhone Tutorial – PhotoApp.zip</a></p>
<p><br class="spacer_" /></p>
<p>原文见：<a title="Permanent Link to Getting Images From The iPhone Photo Library Or Camera Using UIImagePickerController" rel="bookmark" href="http://icodeblog.com/2009/07/28/getting-images-from-the-iphone-photo-library-or-camera-using-uiimagepickercontroller/">Getting Images From The iPhone Photo Library Or Camera Using UIImagePickerController </a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e4%bd%bf%e7%94%a8uiimagepickercontroller%e4%bb%8eiphone%e7%85%a7%e7%89%87%e5%ba%93%e6%88%96%e7%85%a7%e7%9b%b8%e6%9c%ba%e8%8e%b7%e5%8f%96%e5%9b%be%e5%83%8f/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone程序的文档目录</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95#comments</comments>
		<pubDate>Thu, 04 Feb 2010 06:09:12 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=868</guid>
		<description><![CDATA[最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。

今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：

12NSString* documentsDirectory &#160;= &#91;NSHomeDirectory&#40;&#41; 
&#160; &#160; &#160; &#160; stringByAppendingPathComponent:@&#34;Documents&#34;&#93;;

方法二：

12NSArray *paths = NSSearchPathForDirectoriesInDomains&#40;NSDocumentDirectory, NSUserDomainMask, YES&#41;; 
NSString *documentsDirectory = &#91;paths objectAtIndex:0&#93;;
]]></description>
			<content:encoded><![CDATA[<p>最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。</p>
<p><br class="spacer_" /></p>
<p>今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> documentsDirectory &nbsp;<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSHomeDirectory<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Documents&quot;</span><span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p><br class="spacer_" /></p>
<p>方法二：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span>paths <span style="color: #002200;">=</span> NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span>; <br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>documentsDirectory <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>paths objectAtIndex<span style="color: #002200;">:</span>0<span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPad到底是什么？</title>
		<link>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipad%e5%88%b0%e5%ba%95%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f</link>
		<comments>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipad%e5%88%b0%e5%ba%95%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f#comments</comments>
		<pubDate>Wed, 03 Feb 2010 02:48:26 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[闲谈]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=860</guid>
		<description><![CDATA[恕我孤陋寡闻，一直对Apple的平板电脑没有过多的关注，以为就是一台带触摸屏的Macbook。在我的Macbook Pro被盗后，还准备买一台进行iPhone的开发工作。但随着iPad新闻的发布，我发现iPad不过就是一台大号的iPod Touch。我觉得有下列弱点：


不支持后台运行 &#8211; 这无疑是iPad的致命弱点。如果说iPod Touch和iPhone不支持多任务是为了最优化的用户体验，我还可以理解。但作为一台拥有如此先进的OS的电脑，我不知为何Apple一直抱定这个设计理念。简直让人觉得回到了DOS时代。
不支持Flash &#8211; 仍然无法像使用普通浏览器一样访问Flash支持的网站。使其网络浏览功能大打折扣。
不带摄像头 &#8211; 在视频聊天如此流行的今天，在这样一个高端的设备上，加上一个前置摄像头应该是必备的选择吧？ 
大尺寸的屏幕 &#8211; 这也是缺点？没错。虽然我觉得大屏幕确实有许多好处（特别是看电子书），但是如果它具有Laptop或Tablet的尺寸而仅仅具有掌上电脑的功能，这应该是缺点多过优点了。另外，试想一下，拿着这么个大家伙在地铁上摇头晃脑地玩着保龄或赛车游戏，是不是有那么点脑残？


总而言之，我觉得iPad的设计理念互相矛盾，定位不明确，它不过是苹果公司另一个噱头，它的出现无非是进一步利用其极其成功的App Store模式，最大地获取利润的一种方式罢了，因此我并不看好它的前景，大家觉得呢？

]]></description>
			<content:encoded><![CDATA[<p>恕我孤陋寡闻，一直对Apple的平板电脑没有过多的关注，以为就是一台带触摸屏的Macbook。在我的Macbook Pro被盗后，还准备买一台进行iPhone的开发工作。但随着iPad新闻的发布，我发现iPad不过就是一台大号的iPod Touch。我觉得有下列弱点：</p>
<p><br class="spacer_" /></p>
<ul>
<li>不支持后台运行 &#8211; 这无疑是iPad的致命弱点。如果说iPod Touch和iPhone不支持多任务是为了最优化的用户体验，我还可以理解。但作为一台拥有如此先进的OS的电脑，我不知为何Apple一直抱定这个设计理念。简直让人觉得回到了DOS时代。</li>
<li>不支持Flash &#8211; 仍然无法像使用普通浏览器一样访问Flash支持的网站。使其网络浏览功能大打折扣。</li>
<li>不带摄像头 &#8211; 在视频聊天如此流行的今天，在这样一个高端的设备上，加上一个前置摄像头应该是必备的选择吧？ </li>
<li>大尺寸的屏幕 &#8211; 这也是缺点？没错。虽然我觉得大屏幕确实有许多好处（特别是看电子书），但是如果它具有Laptop或Tablet的尺寸而仅仅具有掌上电脑的功能，这应该是缺点多过优点了。另外，试想一下，拿着这么个大家伙在地铁上摇头晃脑地玩着保龄或赛车游戏，是不是有那么点脑残？</li>
</ul>
<p><br class="spacer_" /></p>
<p>总而言之，我觉得iPad的设计理念互相矛盾，定位不明确，它不过是苹果公司另一个噱头，它的出现无非是进一步利用其极其成功的App Store模式，最大地获取利润的一种方式罢了，因此我并不看好它的前景，大家觉得呢？</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e9%97%b2%e8%b0%88/ipad%e5%88%b0%e5%ba%95%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
