Cocoa Tips

版本兼容性检查

检查某个系统常量是否存在

  • 比如UIKeyboardFrameEndUserInfoKey是从iOS 3.2开始支持的, 要在之前的系统版本中使用该值, 需使用UIKeyboardBoundsUserInfoKey.
    if (&UIKeyboardFrameEndUserInfoKey != nil)
  • {
  •     // Available.
  • }
  • else
  • {
  •     // Do something else.
  • }

检查某个系统类库是否存在

  • 比如在iOS 4.0之后加入了ALAssetsLibrary.
    Class ALAssetsLibraryClass = NSClassFromString(@"ALAssetsLibrary");
  • if (ALAssetsLibraryClass)
  • {
  •     // Do something related to the library.
  • }

检查某个函数是否存在

  • ImageIO是iOS 4.0之后才有的类库, 但它是一套C的类库, 要检查其是否存在, 就要检查某个函数是否存在.
    系统声明如下:
    IMAGEIO_EXTERN CGImageSourceRef CGImageSourceCreateWithData(CFDataRef data, CFDictionaryRef options)  IMAGEIO_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_4_0);

  • 检查方法:
    if (CGImageSourceCreateWithData != NULL)
  • {
  •     // ImageIO exists.
  • }

检查某个类是否实现指定方法

  • iOS 4.0中的ALAssetsLibrary, 可以将照片存入系统相册, 但是iOS 4.0和iOS 4.1有不同的方式调用存入相册的方法. 以下存入相册的方法分为三种:
    • 系统支持带入元数据存入相册 (iOS 4.1及以上) 
    • 系统支持带入相片方向存入相册 (iOS 4.0及以上) 
    • 原始存入相册方式 (iOS 2.0及以上)
      // 如果支持Assets, 则使用Assets.
    • Class ALAssetsLibraryClass = NSClassFromString(@"ALAssetsLibrary");
    • if (ALAssetsLibraryClass)
    • {
    •     ALAssetsLibrary *assetsLibrary = [[[ALAssetsLibrary alloc] init] autorelease];
    •     if (&UIImagePickerControllerMediaMetadata != nil && [assetsLibrary respondsToSelector:@selector(writeImageToSavedPhotosAlbum:metadata:completionBlock:)])
    •     {
    •         // 如果支持存储metadata, 则存储. 4.1及以上支持.
    •         [assetsLibrary writeImageToSavedPhotosAlbum:[originalImage CGImage] 
    •                                           metadata:[info objectForKey:UIImagePickerControllerMediaMetadata] 
    •                                     completionBlock:^(NSURL *assetURL, NSError *error) {
    •                                     }];
    •     }
    •     else if ([assetsLibrary respondsToSelector:@selector(writeImageToSavedPhotosAlbum:orientation:completionBlock:)])
    •     {
    •         // 如果不支持存储metadata, 则只存储图片和方向. 4.0及以上支持.
    •         [assetsLibrary writeImageToSavedPhotosAlbum:[originalImage CGImage] 
    •                                         orientation:(ALAssetOrientation)[originalImage imageOrientation] 
    •                                     completionBlock:^(NSURL *assetURL, NSError *error) {
    •                                     }];
    •     }
    • }
    • else
    • {
    •     UIImageWriteToSavedPhotosAlbum(originalImage, NULL, NULL, NULL);
    • }
  • 检测系统是否支持多任务
    - (BOOL)isMultitaskingCapable
  • {
  •     UIDevice *device = [UIDevice currentDevice];
  •     BOOL backgroundSupported = NO;
  •     if ([device respondsToSelector:@selector(isMultitaskingSupported)])
  •     {
  •         backgroundSupported = device.multitaskingSupported;
  •     }
  •     return backgroundSupported;
  • }

具体案例

设置UIWindow的rootViewController

iOS 3.x中UIWindow采用加入view的方式, iOS 4.0及以上系统采用了直接设置rootViewController的方式. 推荐使用最新的API, 而兼容iOS 3.x的API.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    // Override point for customization after application launch.


    if ([UIWindow instancesRespondToSelector:@selector(rootViewController)])

    {

        self.window.rootViewController = self.viewController;

    }

    else

    {

        [self.window addSubview:self.viewController.view];  

    }


    [self.window makeKeyAndVisible];


    return YES;

}



调试

日志开关

  • 一般来讲在应用提交App Store时需要关闭NSLog打印出来的日志信息. 如果时临时注释代码的方式, 会比较繁琐, 也容易出错. 可以采用声明一个宏的方式, 只有在调试模式才开启NSLog输出的日志.
    #ifdef DEBUG
  • #   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
  • #else
  • #   define DLog(...)
  • #endif
  • // ALog always displays output regardless of the DEBUG setting.
  • #define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

  • 甚至可以加入UIAlertView的提醒.
    #ifdef DEBUG
  • #   define ULog(fmt, ...)  { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; [alertView release]; }
  • #else
  • #   define ULog(...)
  • #endif

NSZombieEnabled

  • 当程序是因为EXC_BAD_ACCESS而崩溃的情况时, 可以考虑在环境变量中开启NSZombieEnabled. 开启后会把object错误释放的消息打印在控制台上.

NSAssert

  • 使用NSAssert可以在开发过程中非常方便的确定问题所在,但是在发布程序时需要手动隐藏掉这些用于调试的assert。方法:设置编译属性,在Build Settings页面中修改 Preprocessing Macros的值,对 release 和 distribution 增加 NS_BLOCK_ASSERTIONS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值