3

我正在编写一个可以在 iPad 和 iPhone 上本地运行的通用应用程序。我还需要它针对旧设备(那些不能运行 4.0 的设备),所以 3.1 是必须的。

我已经将 Base SDK 设置为最新的可用版本(4.2),并将部署目标设置为 3.1。我正在进行大量运行时检查,以便仅在正确的设备/版本上调用相应的方法。

我在 iPad 中使用的其中一件事是 UISplitViewController。分配 splitViewController 委托时,编译器会抛出警告,因为类接口没有明确采用 UISplitViewControllerDelegate 协议,我担心如果我声明它这样做,应用程序将在没有 UISplitViewController 的旧设备上崩溃/UISplitViewControllerDelegate。

抑制编译器警告的最佳方法是什么?我应该声明一个“空”的 UISplitViewControllerDelegate 吗?如果是这样,我可以在运行时有条件地制作它吗?还是我应该让相应的类接口符合协议而不用担心旧设备?

最好的,

4

3 回答 3

1

我没有尝试过,但我很确定您可以继续无条件地采用协议,即使该类可能在没有协议的较旧运行时使用。这就是为什么:

定义协议的所有信息都包含在声明 .h 文件的 .h 文件中@protocol。当您采用协议时,该协议声明会在您的 .h 文件中的某个位置导入(可能是通过#import <UIKit/UIKit.h>)。

当运行时需要了解协议的某些内容时,它会引用一个“协议对象”,您通常会在源代码中通过执行@protocol(MyProtocolName). 根据Objective-C编程语言文档中标题为Protocol Objects的部分,当遇到这样的协议引用时,编译器会创建这个协议对象(在编译时) 。

因此,如果您采用协议并编写任何引用协议对象的代码,那么知道所有这些,该协议对象将由编译器创建。即使您在较旧的设备上运行,编译器也应该为您创建该协议对象,所以我认为它不会导致崩溃。

希望这是有道理的。如果我有时间,我可以尝试一下,看看它在实践中是否成立,因为我的设备运行从 3.1 到 4.2 的一系列 iOS 版本。

于 2010-11-05T16:20:31.750 回答
1

您可以使用简单的 C 强制转换来抑制警告:

foo.delegate = (id<UISplitViewControllerDelegate>)self;
于 2010-11-03T04:43:09.533 回答
0

如果您想使用打印并且仍然让应用程序在 4.2 之前运行,同样的问题。基本上它适用于此

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40200
// code for iOS 4.2++
@interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPrintInteractionControllerDelegate>{
#else
// code for iOS til 4.1
@interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>{
#endif

但是...看起来 InterfaceBuilder 无法处理这个问题。在此条件定义之后,所有网点都在 IB 中定义。

那么有更好的解决方案吗?

问候 Gerd

于 2010-11-05T16:00:30.707 回答