使用@objcMembers后私有dynamic变量仍需加@objc?是否为预期行为?
这确实是预期行为!
别担心,你没写错代码——这种看似“冗余”的要求是@objcMembers的设计规则和Realm的底层需求共同导致的,完全符合预期。
为什么会有这个要求?
@objcMembers的核心作用是自动为类的所有非私有成员添加@objc修饰符,但它特意排除了private级别的属性。这是因为Swift中private的本意就是限制属性仅在当前作用域内访问,Objective-C运行时默认不应该获取到这些私有成员。
但Realm的底层依赖Objective-C运行时来处理数据持久化,它需要能访问到你要存储的所有属性——包括你标记为private的那些。所以即使加了@objcMembers,你还是得给私有属性手动加上@objc,才能让Realm识别到它们,同时满足Xcode的编译规则。
结合你的代码分析
看你的示例代码:
@objcMembers class MyObject: Object { @objc dynamic private var text: String = String() @objc dynamic private var youtubeLink: String = String() @objc dynamic private var count: Int = 0 dynamic var isFavorite: Bool = false // ...其他属性 }
isFavorite是默认的internal访问级别,所以@objcMembers自动给它加上了@objc,你不需要手动写。- 而三个
private属性不在@objcMembers的自动覆盖范围内,必须显式加@objc才能被Realm处理,Xcode的报错就是在提醒你这一点。
一个简化的小技巧
如果你不想每次都写@objc,可以把private改成fileprivate——@objcMembers会自动为fileprivate属性添加@objc修饰符,同时依然能保证属性仅在当前文件内可访问:
@objcMembers class MyObject: Object { dynamic fileprivate var text: String = "" dynamic fileprivate var youtubeLink: String = "" dynamic fileprivate var count: Int = 0 dynamic var isFavorite: Bool = false // ... }
这样代码更简洁,也能满足Realm的持久化需求。
内容的提问来源于stack exchange,提问作者Tarek
相关产品推荐
相关产品推荐

