• 无法正确加载@2x的解决办法

    为使用retina显示,我们一般把图片的高分辨率版本存为@2x的形式,但是iOS 4.1以前的版本,如果使用imageWithContentsOfFile是无法保证@2x文件正确加载的。我使用如下方法解决此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // UIImage+Extras.h
    @interface UIImage (Extras)

    - (id)initWithContentsOfResolutionIndependentFile:(NSString *)path;
    + (UIImage*)imageWithContentsOfResolutionIndependentFile:(NSString *)path;

    @end

    // UIImage+Extras.m
    - (id)initWithContentsOfResolutionIndependentFile:(NSString *)path {
        if ( [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0 ) {
            NSString *path2x = [[path stringByDeletingLastPathComponent]
                                stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@",
                                                                [[path lastPathComponent] stringByDeletingPathExtension],
                                                                [path pathExtension]]];
           
            if ( [[NSFileManager defaultManager] fileExistsAtPath:path2x] ) {
                return [self initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:path2x]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
            }
        }
       
        return [self initWithData:[NSData dataWithContentsOfFile:path]];
    }

    + (UIImage*)imageWithContentsOfResolutionIndependentFile:(NSString *)path {
        return [[[UIImage alloc] initWithContentsOfResolutionIndependentFile:path] autorelease];
    }
     
  • 不需重新编译而更改app资源内容的简单方法

    有的时候,我们需要把做好的项目以另外的程序名和内容重新打包,当然我们可以使用建立一个新的target的方法,不同的情况用不同的target表示。我一位朋友luckywr分享了一种更为简单的方法,特别适合于只需少量更改了项目的内容(比如,更改程序的图标)。其思路也非常简单,就是在更改内容后使用命令行对app重新进行数字签名,而不需要再次对整个程序进行编译了。

    下面是他使用的方法:

    codesign -f -vv -s [Identity] [appPath]

    Identity 是授权文件,是在keychain里使用的私钥的名字。

    比如:codesign -f -vv -s “luckywr” /Users/luckywr/Desktop/xxxx.app

    在此感谢luckywr朋友。

     
  • Xcode 4闲谈

    Xcode 4终于千呼万唤发布了,诚然它有太多亮点,不过目前还是感觉不够稳定,还有很多功能都不会用。举个简单的例子,在Xcode 3下,使用Analyze时有非常多的误报,但Xcode 4似乎又走了另一个极端,几乎没有什么报告。我有一个程序明显有memory leak(因为我安装了状态条可以显示内存的软件),但Analyze的结果是没有potential leak,而且使用Instrument也没有发现任何leak,不知是不是我还不太会用。

    另外,还有一些以前比较熟练的事情在Xcode 4下,都不会做了。比如, 当程序出现EXC_BAD_ACCESS时添加NSZombieEnabled环境变量开始都找不到地方。最后终于找到了,在:

    Product -> Edit Scheme…



    4月1日更新:
    今天发现一个有趣的现象。突然发现以前为Xcode项目添加静态库子项目的方法不再适用,添加的项目文件只是一个文件而已。后来经过研究才发现是因为Xcode打开了另外一个项目的缘故。关掉另一个Xcode后,问题解决。

     
  • 怎样关闭后台运行

    iOS 4引进了所谓多任务,可以让程序运行于后台,不过对目前大部分程序而言这只是一个鸡肋。有没有办法直接在用户按下Home键后像iOS 4之前的程序一样直接退出呢?方法如下:

    1. 打开info.plist
    2. 加入 UIApplicationExitsOnSuspend 或者选择“Application does not run in background(程序不运行于后台)”
    3. 将其设为 YES
     
  • NSOperation和NSURLConnection

    最近一个客户向我汇报了一个程序的问题。经过分析发现问题是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];     
    }
     
  • 检测当前设备是否为iPad

    今天编写一个程序时需要检测当前设备是否为iPad,正好用到开源Cocos2d库,发现里面是使用下面代码段进行检测的:

     

    1
    2
    3
    4
    5
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [_pages addObject:@"page1-ipad.jpg"];
        } else {
            [_pages addObject:@"page2.jpg"];
        }

    &nbsp

     
  • 程序中读取可用内存

    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]);
     
  • Xcode不支持iPhoe OS 3.2.1的解决方法

    最近iPad升级到iPhone 3.2.1,今天准备进行真机调试,猛然发现Xcode下出现下列错误:


    The version of iPhone OS on “xxxx” does not match any of the versions of iPhone OS supported for development with this copy of Xcode. Please restore the device to a version of the OS listed below. If necessary, the latest version of Xcode is available here.


    Google 了一下,发现是3.2.1的目录在DeviceSupport下不存在。解决办法是用最接近的OS版本使用ln命令进行链接。不过在操作过程中有两个问题:


    1. 不知什么原因,ln -s 命令后总是为文件而不是目录
    2. 不知OS 3.2的build number


    于是,采用最笨但最为有效的方法:


    在/Developer/Platforms/iPhoneOS.platform/DeviceSupport目录下创建3.2.1目录,然后,将3.2下所有文件及目录复制到3.2.1下,重新启动Xcode,问题解决。

     
  • 修改公司名称的“新”方法

    以前发过一篇文章介绍怎样修改Xcode中的公司名称,见怎样替换Xcode中__MyCompanyName__

    现在(不知是从Xcode哪个版本开始,我是3.2.3)可以有更简单的方法修改公司名称,而且还可以在基于项目修改。方法如下:

    1. 右击项目名称,选择“Get Info…”
    2. 在“General Settings”一栏中可以看到“Organization Name”,修改它,那么本项目中的公司名称就修改了。

     
  • 怎样离线使用iPhone SDK文档

    我是用Dell机安装的雪豹系统,由于没有无线网卡的支持,所以上网很不方便。在使用Xcode进行iPhone编程时,有时需要参考iPhone SDK的文档,不过每次Control+Click后,Xcode都会试图连接Internet,进行在线读取。有什么方法能够把资料下载到硬盘上进行离线阅读吗?


    答案是肯定的。首先去Xcode的Preference中的Documentation Sets下,选择所需的docset,这里是iPhone 4.0 Reference Library,右击选择“Get Info…”,找到Feed URL:


    http://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone4_0.atom


    用浏览器打开,下面列出了许多版本,在Windows下你就可以使用迅雷下载了。


    下载后,拷贝到Mac的/Developer/Documentations/Docset目录下,使用终端命令:

    sudo xar -xf 下载的文件名.xar



    将其解压,然后使用:

    sudo chown -R -P devdocs 解压后的文件名.docset



    将文档的所有者改为devdocs。打开Xcode就可以离线浏览了。