支持旧版OS X SDK中的新功能

时间:2014-04-22 12:46:25

标签: objective-c xcode xcode5 osx-mavericks osx-leopard

我通过为开源项目(IPMenulet)做出贡献,更多地了解了Cocoa,Objective-C和Xcode;该项目最初支持OS X 10.5。

在我的仓促中,似乎我使用旧版SDK不支持的SDK元素(NSJSONSerialization@autoreleasepool编译器指令)添加了功能。现在,我试图确定如何恢复对10.5的支持

选项:

  • NSJSONSerialization - 我想我可以切换到JSONKit
  • @autoreleasepool {} - ?
  • @properties - 添加@synthesize和IVAR

问题:

  • 有没有办法(编译器指令?)使用较新的SDK元素,如果操作系统支持它,必要时切换到旧元素?如果是这样,是否更好地在特定于版本的方法中重构功能(例如getJSONlegacygetJSON)?
  • 将原始项目标记为单独的分支(以允许它被增强)会更好吗?

2 个答案:

答案 0 :(得分:1)

不同的功能涉及不同的OS组件,它定义了如何在多个OS X版本中使用功能。这是我粗略的分类:

  • 功能完全由某个框架提供。例如,NSJSONSerialization在Mac OS X 10.7+中可用。您可以对所有OS版本使用相同的解决方案,或者在运行时检查某些功能是否可用。例如,

    if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)])
        [view setAcceptsTouchEvents:YES];
    

    有关多个SDK支持的更多详细信息,请参阅SDK Compatibility Guide. Using SDK-Based Development

  • 功能完全由编译器提供。例如,@autoreleasepool,文字。

  • 功能由编译器和运行时提供。例如,默认@property综合。有关详细信息,请参阅Objective-C Feature Availability Index

  • 功能取决于与应用程序链接的SDK。它更多地是关于行为更改,AppKit Release Notes中的向后兼容性部分中描述了这种机制。

现在回到你的问题。有一种机制可以在运行时检查功能是否可用,通常respondsToSelector:可以完成这项工作。我建议公开一种适用于所有操作系统版本的方法。并且仅在该方法内部存在OS版本之间的差异。例如,

- (NSString *)base64EncodingForData:(NSData *)data {
    NSParameterAssert(data);
    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
        return [data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
    }
    else {
        // Manual encoding using <Security/SecEncodeTransform.h> and kSecBase64Encoding.
    }
}

您可以创建一些1.1维护分支,在master中执行所有工作,并仅合并到维护分支错误修正。因此,从维护分支,您将发布1.1.1并从主1.2发布。这是一种可行的方法。但是你不能无限期地支持Mac OS X 10.5,所以你需要决定你将支持哪种IPMenulet版本。

答案 1 :(得分:1)

在某种程度上它有所帮助,经典版本:

@autoreleasepool { ... code ... }

当时:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

... code ...

[pool drain];

drain比普通release更受欢迎,因为它可以正常使用(现在也已弃用)OS X垃圾回收。但它算作一个释放,所以没有内存泄漏,你也不应该释放。