【问题标题】:Universal App (iPad+iPhone) targeted to older (iOS < 4) devices - conditionally adopt a protocol?针对较旧(iOS < 4)设备的通用应用程序(iPad + iPhone) - 有条件地采用协议?
【发布时间】:2010-11-03 04:12:56
【问题描述】:

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

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

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

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

最好的,

【问题讨论】:

    标签: objective-c xcode universal-binary


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我还没有尝试过,但我很确定您可以继续并无条件地采用协议,即使该类可能用于没有协议。原因如下:

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

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

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

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

      【讨论】:

        【解决方案3】:

        如果您想使用打印并且仍然让应用程序在 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 中没有这个条件定义之后,所有的 outlet 都定义了。

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

        问候 格尔德

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-24
          • 1970-01-01
          • 2016-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多