【问题标题】:Checking for availability of iOS classes (rather than methods) in MonoTouch在 MonoTouch 中检查 iOS 类(而不是方法)的可用性
【发布时间】:2013-01-15 01:24:36
【问题描述】:

MonoTouch 公开了 RespondsToSelector 方法,用于检查 iOS 版本中方法的可用性。

但是我似乎不知道如何对类可用性执行类似的检查。
Apple documents it here 在 iOS 4.2+ 中,您应该尝试访问所需类的静态 class 选择器。例如:

if ([EKReminder class]) 
{
    ....
}

然而,这似乎并没有暴露。我认为它类似于my previous question here,因为要在 MT 中实现这一点,它需要在每个 MT 类型上显式映射 Class 静态属性。

所以我想我的问题是,我应该只使用旧的 iOS 4.2 之前的技术吗?即:

Class cls = NSClassFromString (@"EKReminder");
if (cls) 
{
    ...
}

我认为映射到:

var iosClass = Class.GetHandle("EKReminder");
if ( iosClass != null )
    ...

或者使用Messaging中提供的互操作方法手动调用选择器?

或者其他我没有找到的方法?

【问题讨论】:

    标签: ios xamarin.ios weak-linking


    【解决方案1】:

    安全检查正在使用:

    if (Class.GetHandle (typeof (EKReminder)) != IntPtr.Zero) {
        // we know we can use EKReminder
    }
    

    但是它有点昂贵,因为它涉及反射。 Objective-C 名称可以与 .NET 名称不同(例如,NSURLNSUrl,只能通过反映 Register 属性来找到)。

    如果您知道 Objective-C 的名称,那么您可以使用非类型安全的重载来跳过反射。例如

    // checking for NSUrl would not work
    if (Class.GetHandle ("NSURL") != IntPtr.Zero) {
        // we know we can use NSUrl
    }
    

    再次重申(并且将我的答案概括为每个人),使用 iOS 版本对非硬件功能进行运行时检查通常是最好/更容易/更快的。

    if (UIDevice.CurrentDevice.CheckSystemVersion (5,0)) {
        // we know feature X was added in 5.0
    }
    

    【讨论】:

      【解决方案2】:

      只需使用 iOS 4.2 之前的技术:

      var iosClass = Class.GetHandle ("EKReminder");
      if (iOSClass != null)
          ...
      

      Apple 推荐的方法似乎是 gcc/clang 的特殊情况,在 MonoTouch 中不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-28
        • 2014-01-13
        • 1970-01-01
        相关资源
        最近更新 更多