iOS 4引进了所谓多任务,可以让程序运行于后台,不过对目前大部分程序而言这只是一个鸡肋。有没有办法直接在用户按下Home键后像iOS 4之前的程序一样直接退出呢?方法如下:
- 打开info.plist
- 加入 UIApplicationExitsOnSuspend 或者选择“Application does not run in background(程序不运行于后台)”
- 将其设为 YES
iOS 4引进了所谓多任务,可以让程序运行于后台,不过对目前大部分程序而言这只是一个鸡肋。有没有办法直接在用户按下Home键后像iOS 4之前的程序一样直接退出呢?方法如下:
我有一个程序需要检测UIWebView是否有touch动作,不幸得很,UIWebView上的touchesBegan等事件无法被检测。在网上查了一下,有许多解决方法,比如在UIWebView上再加一个透明的UIView,重置UIWindow的sendEvent或重置UIWebView的hitest方法等等,要么就是方案不太完美,要么就是太过复杂,经过实验我使用的这种方法最为简单(否则我也没有时间写在这里了),当然我只要求检测UIWebView上有touch动作即可。我的方法是使用UITapGestureRecognizer。关键的地方有两点,请看我的代码(我的代码是在一个UIViewController中):
1 2 3 4 5 | UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [self.view addGestureRecognizer:singleTap]; singleTap.delegate = self; singleTap.cancelsTouchesInView = NO; [singleTap release]; |
第三行是第一个关键的地方,就是必须设置UITapGuestureRecognizer的delegate(一般我们直接使用initWithTarget,无需设置其delegate)。
第二个关键的地方是在下列delegate方法return YES。
1 2 3 4 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } |
做到这两点,你的UIWebView就可以响应touch事件了,你可以使用不同的UIGestureRecognizer来满足你不同的要求等。(handleSingleTap方法请自行补上)。
最近一个项目需要用到opengles,由于实在没有时间无法完成自己的引擎,因此开始对cocos2d-iphone引擎进行了研究。经过研究发现一个问题,其模板生成的项目每次都会把整个cocos2d的源代码拷贝进新项目中,这样每次cocos2d-iphone进行更新时都会带来麻烦,而且如果多个项目使用cocos2d-iphone,非常的不方便。我在网上搜索了一下,发现了了这个网站,介绍了怎样将cocos2d-iphone编译成静态库的方法,与我的想法不谋而合。不过该网站中的模板只适用于0.99.4,于是我修改了一下,让其可以运行于0.99.5。下面是主要步骤:
1. 下载cocos2d-iphone 0.99.5 template模板。
2. 解压到/$HOME/Library/Application Support/Developer/Shared/Xcode下
3. 下载cocos2d-iphone 0.99.5,解压到你想要的地方。
3. 在Xcode Preferences中找到Source Tree,输入新变量COCOS2D_SOURCE,让其指向cocos2d-iphone 0.99.5的源代码处。
这样,下次你打开Xcode,你就可以使用我的模板创建cocos2d项目了(注意不要安装随cocos2d-iphone下载的模板),以后每次cocos2d-iphone进行更新,你仅仅需要修改COCOS2D_SOURCE变量(当然前提是cocos2d-iphone的编程接口没有改变)。
最近一个客户向我汇报了一个程序的问题。经过分析发现问题是NSURLConnection没有正常工作。记得以前测试时没有问题啊。后来上网查到原来在iOS 4.0以后,NSURLConnection无法在NSOperation中正常运行,换句话说,NSURLConnection只能运行于主线程。解决方法其实倒是蛮简单(比如我的程序在download中):
1 2 3 4 5 6 7 8 9 10 11 12 | -(void)download { // NSURLConnectionn won't work if it's not in the main thread if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(download) withObject:nil waitUntilDone:NO]; return; } NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_urlString]]; _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; } |
前一阵子读到一篇介绍CALayer(这里简单地称其为层)的教程,比较简单易懂,适合初学者,我在这里就不完全翻译了,只是把要点说明一下。
今天编写一个程序时需要检测当前设备是否为iPad,正好用到开源Cocos2d库,发现里面是使用下面代码段进行检测的:
1
2
3
4
5 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[_pages addObject:@"page1-ipad.jpg"];
} else {
[_pages addObject:@"page2.jpg"];
}
 
有时程序崩溃根本不知错误发生在什么地方。比如程序出现EXEC_BAD_ACCESS的时候,虽然大部分情况使用设定NSZombieEnabled环境变量可以帮助你找到问题的所在,但少数情况下,即使设定了NSZombieEnabled环境变量,还是不知道程序崩溃在什么地方。那么就需要使用下列代码进行帮助了:
1 2 3 4 5 6 | #ifdef _FOR_DEBUG_ -(BOOL) respondsToSelector:(SEL)aSelector { printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]); return [super respondsToSelector:aSelector]; } #endif |
你需要在每个object的.m或者.mm文件中加入上面代码,并且在other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。
iPhone/iPad的内存十分紧张,所以有时进行调试时可能需要读取当前可用内存。其实挺简单,见下列代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #import <mach/mach.h> #import <mach/mach_host.h> @implementation Utils + (double)getAvailableMemory { vm_statistics_data_t vmStats; mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT; kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount); if (kernReturn != KERN_SUCCESS) { return NSNotFound; } return (vm_page_size * vmStats.free_count); } end |
使用方法更简单,比如:
1 | NSLog(@"Available memory (KB) = %f",[Utils getAvailableMemory]); |
这几天测试IAP时,总是出现下列错误:
You’ve already purchased this but it hasn’t been downloaded…..
然后就是,Transaction Failed,错误原因是:无法连接iTune Store。上网查了一下很多人说是iTunes Store的问题,等几天就好了,但我用另一个iDP的账户又没有问题。进过调试,最后发现问题出在iTune Store 的 test account上,原来我没有为新iDP账户创建test account,这原来是个低级错误,不过Apple的错误信息也太容易误导人了吧?