我认为我的部分问题是因为Swift 4改变了@objc
之类的工作方式。
有很多教程浮出水面,有很多不同的值,我不能选择在什么版本上工作的东西,以便弄清楚如何使它在这个< / em>版本。
let delegate = UIApplication.shared.delegate as! AppDelegate
delegate.addObserver(self, forKeyPath: #keyPath(AppDelegate.session), options: [], context: nil)
// Warning: Argument of #keyPath refers to non-'@objc' property 'session'
将@objc
添加到var声明只是告诉我在Objective-C中无法引用APISession。这似乎导致了要求我将我想要使用此工具的每个类/变量暴露给Obj-C的路径,而这似乎是倒退 - 这是一个更新的功能,正如我所理解的那样,它只是奇怪的Apple不会让它在Swift中本地运行。对我而言,这表明我在某个地方某种程度上误解或误用某些东西。
答案 0 :(得分:6)
根据docs:
在Objective-C中,键是一个标识对象特定属性的字符串。键路径是一串点分隔键,用于指定要遍历的对象属性序列。
值得注意的是,#keyPath
的讨论可在标题为“与Objective-C API交互”的部分中找到。 KVO和KVC是Objective-C的特色。
文档中的所有示例都显示了从NSObject继承的Swift类。
最后,当您在Xcode中输入#keyPath
时,自动填充功能会告诉您它正在等待@objc property sequence
。
使用#keyPath
输入的表达式将由编译器检查(好!),但这不会消除对Objective-C的依赖。
答案 1 :(得分:0)
这就是我在我的真实项目中应用 #keyPath()的方式。我用它来保存和检索数据到 UserDefaults 以及从 UserDefaults 中获取数据,我将该功能称为 AppSettings 。这是怎么回事...
1)。我有一个协议,名为AppSettingsConfigurable
,其中包含一些东西,它们是我的应用程序的设置功能...
//: AppSetting Protocol
@objc protocol AppSettingsConfigurable {
static var rememberMeEnabled : Bool { get set }
static var notificationEnabled : Bool { get set }
static var biometricEnabled : Bool { get set }
static var uiColor: UIColor? { get set }
}
2)。我有班,我将其命名为AppSettings
。这是通过UserDefaults
//: AppSettings
class AppSettings: NSObject {
fileprivate static func updateDefaults(for key: String, value: Any) {
// Save value into UserDefaults
UserDefaults.standard.set(value, forKey: key)
}
fileprivate static func value<T>(for key:String) -> T? {
// Get value from UserDefaults
return UserDefaults.standard.value(forKey: key) as? T
}
}
3)。这是发生 BIG 的地方。 符合 AppSettings
类以符合我们的协议,并允许使用 #keyPath()实现这些内容。
//: Conform to protocol
extension AppSettings:AppSettingsConfigurable{
/** get & return remember me state */
static var rememberMeEnabled: Bool {
get { return AppSettings.value(for: #keyPath(rememberMeEnabled)) ?? false }
set { AppSettings.updateDefaults(for: #keyPath(rememberMeEnabled), value: newValue) }
}
/** get & return notification state */
static var notificationEnabled: Bool {
get { return AppSettings.value(for: #keyPath(notificationEnabled)) ?? true }
set { AppSettings.updateDefaults(for: #keyPath(notificationEnabled), value: newValue) }
}
/** get & return biometric state */
static var biometricEnabled: Bool {
get { return AppSettings.value(for: #keyPath(biometricEnabled)) ?? false}
set { AppSettings.updateDefaults(for: #keyPath(biometricEnabled), value: newValue) }
}
/** get & return biometric state */
static var uiColor: UIColor? {
get { return AppSettings.value(for: #keyPath(uiColor)) }
set { AppSettings.updateDefaults(for: #keyPath(uiColor), value: newValue!) }
}
}
PS :是否注意到uiColor
与其他地方有所不同?它没有问题,因为它optional
,并且可以接受nil
BOOM ..完成!让我们使用它。.
用法:
//: Saving...
AppSettings.biometricEnabled = true
//: Retrieving...
let biometricState = AppSettings.biometricEnabled // true
仅此而已...