【问题标题】:static let sharedInstance not accessible from Objective C code静态让 sharedInstance 无法从 Objective C 代码中访问
【发布时间】:2018-02-27 10:18:46
【问题描述】:

问题:

在构建主应用程序目标时,无法从 Objective C 代码访问声明的静态 let sharedInstance。

代码:

    @objc public protocol ManagedObjectContextProvider {
          var context: NSManagedObjectContext { get }
    }

@objc public final class ManagedObjectContextProviderImpl: NSObject, ManagedObjectContextProvider {
    public static let sharedInstance: ManagedObjectContextProvider = ManagedObjectContextProviderImpl()

    override private init() {}

    public var context: NSManagedObjectContext {
        return NSManagedObjectContext.mr_default()
    }
}

上下文:

  • 此文件包含在 2 个目标中 [主要 iOS 应用和共享扩展]
  • 在主app的swift to objc生成的header中,swift类的接口生成如下:

    @class NSManagedObjectContext;
    
    SWIFT_PROTOCOL("_TtP4<#MyAppName#>28ManagedObjectContextProvider_")
    @protocol ManagedObjectContextProvider
    @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
    @end
    
    
    SWIFT_CLASS("_TtC4<#MyAppName>32ManagedObjectContextProviderImpl")
    @interface ManagedObjectContextProviderImpl : NSObject <ManagedObjectContextProvider>
    - (nonnull instancetype)init SWIFT_UNAVAILABLE;
    @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
    @end
    
  • 在swift to objc生成的共享扩展头中,swift类的接口是正确生成的,是:

    @class NSManagedObjectContext;
    
    SWIFT_PROTOCOL("_TtP4<MyAppName>28ManagedObjectContextProvider_")
    @protocol ManagedObjectContextProvider
    @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
    @end
    
    
    SWIFT_CLASS("_TtC4<MyAppName>32ManagedObjectContextProviderImpl")
    @interface ManagedObjectContextProviderImpl : NSObject <ManagedObjectContextProvider>
    SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong)       id <ManagedObjectContextProvider> _Nonnull sharedInstance;)
    + (id <ManagedObjectContextProvider> _Nonnull)sharedInstance SWIFT_WARN_UNUSED_RESULT;
    - (nonnull instancetype)init SWIFT_UNAVAILABLE;
    @property (nonatomic, readonly, strong) NSManagedObjectContext * _Nonnull context;
     @end
    
  • 上面指定的 MyAppName 是生成 Swift 到 Obj C 标头时使用的模块名称,主目标和共享扩展都相同

我尝试过的: 1. 在两个头文件中复制相同的类声明[欺骗编译器,但在运行时因“无法识别的选择器”而失败] 2.修改扩展的模块名称,使其具有与目标不同的模块名称

什么不建议作为解决方案: 1. 使用不同的模块而不是属于 2 个目标的文件

【问题讨论】:

  • 你有没有尝试在课堂上使用@objcMembers
  • @objc直接在sharedInstance上?
  • @PPL,我认为该答案的范围对于最新的 swift 不再有效。在使用我的共享扩展目标时,我可以访问共享实例,即使它被声明为静态 let。我的问题是在构建主要目标时我无法达到它。
  • @MilanNosáľ,与 objcMembers 合作。请将其作为解决方案提出,如果您包含有关 objcMembers 使用的简短说明或直接链接到 Apple 文档,那就太好了。谢谢!

标签: ios objective-c swift mix-and-match


【解决方案1】:

要让 ObjC 代码可以访问成员(也可以是 static),您需要将 @objc 修饰符添加到它们,或将 @objcMembers 修饰符添加到类(这是用 @objc 标记所有成员的语法糖)。在documentation 中阅读更多内容。

【讨论】:

  • 我猜扩展模块 swift 版本是“3”,因此这适用于扩展,而主要目标的 swift 版本是“4”并且它不再为类的所有成员生成接口,如果未添加 objcMembers。谢谢你的回答。
猜你喜欢
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多