Xcode

众所周知,在Xcode中的IDE环境中编译和调试程序十分方便,我们在某行代码中设置好断点,当程序执行到该处时,只需要将鼠标放到代码段中的字符串等变量名上面,Xcode就能显示出变量的内容。但如果是一些稍微复杂的变量类型,诸如NSDictionary,还是无法看到字典里的全部字段的内容。如果用NSLog去自己写代码输出的话,又嫌有些麻烦。Google了一下,在伟大的StackOverFlow网站找到一个好方法。

这个时候,我们可以开启Debuger,来追踪到具体的内容。在代码的断点处使用快捷键command+shift+Y,调出Debuger窗口,在左侧选择你的代码文件,右侧会列出该代码段的变量列表,选择你所需要追踪的数据,这里我找到了要查看的变量parameters,这是一个NSDictionary类型。点击右键,选择Print Description to Console。如下图所示:

xCode-Debuger
找到需要查看的变量名

然后打开Xcode的控制台(command+shift+R),就能看到详细的信息了。很简单吧,高手可以无视了,对于我这个Xcode菜鸟来说,真的很方便了。

NewImage
数据显示在控制台了

VN:F [1.9.22_1171]
Rating: 8.4/10 (7 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 2 votes)

image

iPhone4国行版的发售,又掀起了一股热潮。最开心的要数国产的iPhone开发者,因为目前4.1版尚未越狱,要装各种软件和游戏,只有去App Store购买。iPhone4卖疯了,相应的iPhone的软件也卖疯了。坛子里不少开发者爆料收入翻了四翻,更有甚者,销量提高了十倍以上。PopCap曾经说过,他们的植物大战僵尸的iPhone正版在中国内陆销售额非常高,在全世界的国家中排在前列。

自己拿到iPhone4的第一件事就是下载iOS最新的4.1版SDK,然后在iPhone4下看看自己那些个小软件的现实效果。果不其然,不少图标和界面元素在iPhone4下都显得略微模糊和粗糙,但是不太影响软件的正常使用。于是开始研究iPhone4高清屏的程序开发方式。

iPhone4以前的机器屏幕分辨率为320×480,iPhone4直接翻了一倍640×960,好家伙,要赶上我的笔记本电脑的分辨率了。在这种分辨率下,以往程序的一些图片元素不可避免地由于放大的缘故变得粗糙起来。不过iOS的系统框架的那些按钮字体导航等界面元素,可以自动适应iPhone4的高清屏幕,也就是说,基本上所有能在3GS上跑的软件,在iPhone4下面没有太大的问题。但是对于游戏来说,不会去用iOS的界面原生空间,所以在3GS下清晰的游戏,到了iPhone4不可避免地杯具起来……

其实同时为iPhone4及以前版本的手机开发程序不用做太多的工作。不需要添加任何代码来检测分辨率等工作,代码还是用一套,只不过资源文件另外准备一套iPhone4的即可。iOS做了一个系统底层的fix,会根据当前机器的分辨率来自动加载不同的资源。使用方法极其极其简单,在为iPhone4准备的资源后面加上“@2x”字样即可,什么工作都不用,程序就自然支持高清了。

例如在3GS下界面某个元素的文件名为“button.png”,那么为iPhone4准备的元素就为“button@2x.png”即可,iOS会在底层根据情况自动加载不同的图片。非常智能和优雅的解决方案。

那么用cocos2d写的游戏程序呢?一样的,新版的cocos2d已经开始支持了iPhone4的高清屏,为了避免和iOS冲突,它的解决方案是在资源后面加上“-hd”。用points方式撰写位置,不用改动任何代码。只是在Pixels层级可以获得高清的像素值。

这里有一篇文章,详细讲述了iPhone4高清屏的开发事项,当然最好是用cocos2d 0.99.5版本,支持得相当好:

http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:how_to_develop_retinadisplay_games_in_cocos2d

不过在使用Box2d的过程中,发现Box2d的坐标似乎是全部按照Pixels来进行定位,使用过程中发现了蛮多的问题……

VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

iPhone Developer:“This is whyIsellbeer”

原作者Jamie ZawinskiNetscapemozilla.org的创始人。 本文由吴安寿翻译。

DaliClock2.31(一款为Mac设计的数字时钟软件)现在已经释出。 我要做iPhone/iPad的移植工作。这是相当可笑的难处,因为我拒绝为MacOSX代码库增设分支:桌面系统和手机系统都被差别不大的相同的操作系统所支持,所以它应该是一组与桌面应用和iPhone应用有着类似的应用编译,但只是在规模上小一些的代码群(注:if,def可能是代码的一种别称吧。)。对不? 哦,哈哈哈哈!

我想可以非常肯定地说MacOS的兼容性要比iPhone好得多。这里面满着各种白痴的例子。这就是它如何在桌面系统上运行的代码。

    NSColorfg=[NSColorcolorWithCalibratedHue:hsaturation:sbrightness:valpha:a];

    [fggetRed:&rgreen:&gblue:&balpha:&a];

    [fggetHue:&hsaturation:&sbrightness:&valpha:&a];

    但是在手机系统上却是这样的:

    UIColorfg=[UIColorcolorWithHue:hsaturation:sbrightness:valpha:a];

    constCGFloat*rgba=CGColorGetComponents([fgCGColor]);

    //Oh,youwantedtogetHSV?Sorry,writeyourown.

    //哦,你想要HSV?对不起,你自己写吧。

    这里充满着很多像这样愚蠢的东西。你是否认为有些人看着旧代码并说:“你知道的,为了使它在iPhone上能够更加有效地运行,我们不得不重新命名 这些类,而且必须保证:这些新的类通过他们的方式,有完全不同的API和使用完全不同的参数能够完成旧库曾经做过的同样的事情。这是使这个平台能够成功的唯一方法。不是这样的。他们起用一些实习生(新生的),这些人对旧库完全不了解,只会埋头重写一个,而忽略了早已存在的代码、表达式、类等。现在都2010了。我们还要在如何通过围绕像素来成像进行创新?这是真的? 你可以通过许多定义(#defines)来解决一些这类愚蠢的行为。但是在一大堆方法中的API也是随时会脱节的。所以只会招来更多的悲剧。如果你有一个程序需要控制很多的颜色,你可以想象一个充满“ifdeffy”的世界给你造成的麻烦有多大。

     参数选择作为常用的解决方案就足够了。我最后几乎理解绑定,当你必须使用NSUserDefaultsController和NSUserDefaults进行比较时,你就对此有了模糊的概念。但是现在我们要猜测 iPhone 缺乏什么?绑定?还是NSUserDefaultsController。但是事实上,它拥有NSUserDefaults。我真的无法解释。

     此外还有。

     我基本上已经放弃了试图让Cocoa(注:Cocoa是MacOSX上原生支持的应用程序开发框架)或者Quartz(注:Quartz是位于MacOSX的Darwin核心之上的绘图库)的任何查兼容版本能够同时运行在这两个平台之上。我的做法由于像上面提到的那些随意的API使之成之变成一个由#ifdefs组成的令人发疯的迷宫。庆幸的是我早已把那个令人头疼的例子。最后我要说:“操,iPhone是 运行OpenGL,对吧?”我刚刚在GL重写了显示层,并扔掉了那些该死的Quartz代码。(让我们记住我在编写这个程序时所做的疯狂的复杂的事情吧:我有一个位图,我让它用两种颜色快速地在屏幕上显示,并且时不时地改变颜色。这真他妈琐碎,是吧?哦,呵呵呵呵。)

     所以我在OpenGL里重写了它,就只是将我的位图倾倒入参照纹理中去。 这也是你们当中的人会笑话我的地方,因为我不知道iPhone 居然运行OpenGLES!当然它有一个特点,就是与OpenGL打交道比iPhone必须与Mac系统打交道的事情要少。

     我期待这个常用的在创造OpenGL上下文环境和要求颜色缓冲时的“ifdef” 疯狂乱舞。因为没有指定的OpenGL跨平台的语言去开始,但是这却不是我所期待的。我至今仍对此目瞪口呆:这个OpenGLES居然移除了glBegin()和glVertex()。

     不,真的,真的没有。

     这就像OpenGL的特征定义。所以OpenGLES只是OpenGL微不足道的变种而已,就像单轮脚踏车是城市公交车微不足道的变种。如果你能控制得了它,那么其他的不就大致相同了吗?

     再提一下那个该死的情况吧。我几乎明白在嵌入式API中以效率的名义移除要显示的清单的理由(我不喜欢它,因为我的屏幕保护程序倾向于按照清单显示,但我能理解它)。但是你可以glDrawArrays()的形式完全实现glBegin() 和glVertex()的功能。这就是为什么要把它们扔掉的原因。

     那么,我在干嘛呢?

     终于搞定了。我想DaliClock终于可以在iPhone和iPad运行了。但我却不能让它运行在我的手机上,我还没有克制好我的愤怒,因为在我被允许在我买的手机上测试我所编写的程序之前,我必须先向乔布斯上交100美元的什一税。 我想如果我先把我的手机“越狱”(解锁),那么我就能完全控制它。但是上一次我这样做了,手机就 不稳定了,我必须重新安装它。

     所以,你们当中的人已经恳求应用程序商店更改原则允许从源代码建立它,而且如果让我知道它能够在你们的实际设备上运行,那将会非常地酷。

     哦,另外,自从我在OpenGL中改写了它,我注意到:在860MHz PPC G4处理器设备上,全屏模式下,得到一个不错的画面是相当地慢。我的意思是说,那机器只比一个16MHz的Palm Pilot(Palm公司的一款产 品)快53倍,只比8MHzMac128k快107倍。

     这就是为什么我要卖啤酒去了。

VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

本周末抽了点时间,在10点的球赛前开始看WWDC10的keynote。介绍了将要推出的XCode4,似乎用了LLVM的编译方式,编译出来的Runtime效率比GCC提高了25%。而且分析工具也相当强大,直接在代码上生成对象的使用流程曲线箭头图,让我们随时分析在什么地方内存并且内存是如何泄露的。

NewImage.jpg

Xcode3.2.3已经下载回来了,但是一直没有安装,怕和3.2.1版本的冲突。论坛上说,装在不同的目录下即可,于是尝试两套Xcode系统,成功。但是iOS4已经发布,心痒痒地想让自己的iPod touch也跟上潮流,但是害怕安装后就不能在SDK3.1.3的环境下调式了。拿同事的iOS4的真机一试,果然如此,残念。

而后继续泡论坛琢磨。既然XCode3.2.1不能调试iOS4的真机,Xcode3.2.3却可以调试任何版本的iOS机器。同时3.2.3虽然Base SDK最小都是3.2,但是可以编译出适合所有版本系统的二进制文件的!论坛上很多人认为Base SDK只能大于3.2以后就只能在iPad和iPhone4上调试,苹果当然不会这么傻。

这样干,把Base SDK调成3.2(iPad)或者4.0(iPhone4),然后在iPhone OS Deployment Target中选择目标的系统版本,从2.0-4.0全有,就可以编译出那个版本的APP文件了。

NewImage.jpg

搞定了这一点,写完这篇博客,CoCo就要开始正式升级iOS4了,iBooks我来了!祝我成功吧…

VN:F [1.9.22_1171]
Rating: 10.0/10 (2 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

Bug是永远伴随着程序员们的东西,各种各样的情况造成程序crash掉也是家常便饭。Windows下的很多大型软件在崩溃的时候,都会弹出提示框,询问用户是否将crash的信息发送到软件厂商,以供软件开发商debug。App store中的软件也有这个功能,用户在使用软件的时候,如果程序崩溃,错误信息会发送到Apple的服务器中,软件的开发者们可以很方便在后台获得自己程序的crash log,供自己调试。

但随之而来的问题是,我们收到的程序崩溃调试信息多半是汇编语言一样的堆栈代码,同时这些信息并不是在我们debug的时候产生,所以看到这一串crash log的天书,常常无可奈何。Xcode很好的解决了这一问题,它所提供的Orgainzer分析器加上symbolicatecrash,可以分析二进制文件以及源代码和crashlog之间的连接,直接找出源程序中出错的代码行。方法网上到处是,本文不讨论。

但是如果使用symbolicatecrash无法定位到出错的代码行的话,怎么整呢?有一个办法,如下:

首先查看crash log中的崩溃线程,假如是这样的:

Thread 0 Crashed:
0   libobjc.A.dylib               0x00003ec0 objc_msgSend + 24
1   MyApp               0x000036d2 0x1000 + 9938

我们得到了用户发生崩溃情况的内存地址:0x000036d2

然后回到我们应用程序的build目录,目录下一定要包含MyApp.app 和MyApp.app.dSYM两个文件。

在控制台使用dwarfdump命令,解析出内存地址,如: 

dwarfdump –lookup 0x000036d2 –arch armv6 MyApp.app.dSYM

输出信息如下:

dwarfdump.jpg

直接定位到代码的出错行,Cool!

 

 

VN:F [1.9.22_1171]
Rating: 10.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)