我即将创建一个 Cocoa 应用程序,我想确保有一天我可以轻松地将它移植到 iPad 甚至 iPhone。我怎样才能提前计划呢?
我知道我将不得不重做所有 NIB,并且可能会设计一个不同的工作流程。
但是代码呢?只是用 UIsomething 替换每个 NSsomething 不会削减它,对吧?关于如何确保我以后不会在脚上开枪的任何提示?
谢谢!
(iPad-SDK 在 NDA 下。为了这个问题,假设我问的是 iPhone,好吗?或者认为 iPhone 有更大的屏幕。)
确保您在应用程序中严格遵守模型-视图-控制器分离。特别是模型不应该依赖于任何控制器或视图。
在移植到 iPhone/iPod touch/iPad 时,您需要更换大部分或所有控制器以及所有 NSView 和 NSCell。如果有的话,您应该能够保留您的 CALayer 子类。您可以通过条件编译重用一个或两个控制器,如果大多数控制器都可以同时工作,但某些部分只能在 Mac 上工作,或者两者都工作但使用完全不同的 API。你应该能够保持整个模型不变。
iPhone 开发人员可能会警告您一些更具体的陷阱,但这是适用于从一种环境过渡到另一种环境的一般规则。(另一种环境转换的示例是为您的应用制作一个或多个命令行工具等效项或补充项,例如 xcodebuild、packagemaker 或 ibtool。)
此外,请查看Foundation 框架参考简介,了解哪些 Foundation 类仅适用于 Mac 和 iPhone。
与桌面 Cocoa 库相比,Cocoa Touch 甚至不支持很多库。您需要考虑 AppKit 与 UIKit 的差异。此外,Objective-C 不允许在 iPhone 上进行垃圾收集。有许多触摸事件只存在于 iPhone 上,而不存在于桌面上。由于手机是与非常个人数据相关的非常个人化的设备,因此 iPhone 的开发受到了更多的限制。
查看这些幻灯片以获得更好的比较:http ://www.slideshare.net/lukhnos/between-cocoa-and-cocoa-touch-a-comparative-introduction
与任何好的项目布局一样,您应该将 UI 与非 UI 组件分开。这不仅仅意味着磁盘布局(尽管这也很有意义),而是使用 MVC 方法,您的控制器 (C) 知道模型 (M) 和 UI (V) 分别呈现。
您可以使用 Key-Value Observing(又名 KVO)来设置模型,这样当它们触发时,它会向任何已注册的侦听器发送通知以进行更新。如果您使用 XIB 生成用户界面,那么当您将对象绑定到显示小部件时会发生这种情况。
因此,您最终可以为您的 iPhone、Mac OS 和(后来的)iPad 使用单独的 XIB——尽管如果您正确调整大小,您可以为 iPhone 和 iPad 使用相同的 XIB。
最后,在某些情况下,您通常需要将逻辑注入模型(例如,添加图像以从方法返回)。在这种情况下,iPhone 和 Mac OS 具有不同的 Image 类。为此,您可以创建以下内容:
MyModel.m // contains the data, no UI
MyModel+UIImage.m // contains a category for adding the UIImage
MyModel+NSImage.m // contains a category for adding the NSImage
类别如下所示:
@interface Host(UIImage)
-(UIImage *)badge;
@end
@implementation MyModel(UIImage)
-(UIImage *)badge
{
if (green)
return [UIImage imageNamed:@"green.png"];
if (red)
return [UIImage imageNamed:@"red.png"];
}
@end
---
@interface Host(NSImage)
-(NSImage *)badge;
@end
@implementation MyModel(NSImage)
-(NSImage *)badge
{
if (green)
return [[NSImage alloc] initWithContentsOfFile: @"green.png"];
if (red)
return [[NSImage alloc] initWithContentsOfFile: @"red.png"];
}
@end
这具有额外的优势,您的单元测试可以只加载模型(不加载任何图像类别),而在运行时您需要处理图像的代码(例如,在视图控制器中)可以加载模型和类别以透明的方式加载徽章 [model badge]
,无论它是为哪个平台编译的。