针对较旧(iOS< 4)设备的Universal App(iPad + iPhone) - 有条件地采用协议?

时间:2010-11-03 04:12:56

标签: objective-c xcode universal-binary

我正在编写一款可在iPad和iPhone上本机运行的通用应用程序。我还需要将它作为旧设备(那些不能运行4.0的设备)的目标,所以3.1是必须的。

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

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

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

最佳,

3 个答案:

答案 0 :(得分:1)

您可以使用简单的C演员来抑制警告:

foo.delegate = (id<UISplitViewControllerDelegate>)self;

答案 1 :(得分:1)

我没有尝试过这个,但我很确定你可以继续无条件地采用协议,即使这个类可以用在没有协议。这就是原因:

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

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

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

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

答案 2 :(得分:0)

同样的问题,如果你想使用打印和stil在4.2之前有app runnig。基本上它适用于此

#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。

那么更好的解决方案呢?

此致 格尔德