【问题标题】:What is the most common way to handle string names for Notifications and UserDefaults key names处理 Notifications 和 UserDefaults 键名的字符串名称的最常用方法是什么
【发布时间】:2018-12-02 22:56:10
【问题描述】:

我将在整个应用程序中使用一些字符串名称作为通知和用户默认名称。

我听说为了类型安全,将notification 名称或UserDefaults 键名称定义为静态字符串并将它们作为类或结构的一部分是一种很好的做法。

为 Notification 和 UserDefault 名称处理字符串名称的最常用方法是什么?

我曾考虑将它们作为全局变量放在我的 AppDelgate 类中,如下所示......

let MY_STRING_NAME = "My string name"

class AppDelegate: UIResponder, UIApplicationDelegate {}

/// Then just use MY_STRING_NAME in other classes. 

或者

class SomeClass {
    let myStringName:String = "My string name"
}
/// Then use myClassInstance.myStringName

最好的方法是什么?

【问题讨论】:

    标签: swift encapsulation


    【解决方案1】:

    UserDefaults 的一个选项是创建一个帮助类来隐藏您正在使用 UserDefaults 的事实。这使您的代码的其余部分看起来就像您正在使用一个简单的类及其属性。

    类似这样的:

    class MyAppPreferences {
        static let shared = MyAppPreferences()
    
        private let highScoreKey = "highScore"
        var highScore: Int {
            get {
                return UserDefaults.standard.integer(forKey: highScoreKey)
            }
            set {
                UserDefaults.standard.set(newValue, forKey: highScoreKey)
            }
        }
    }
    

    在其他代码上,您可以这样做来设置它:

    MyAppPreferences.shared.highScore = 100
    

    或阅读以下内容:

    let score = MyAppPreferences.shared.highScore
    

    为您的应用所需的每个应用偏好添加计算属性和私钥。这使您的其余代码更加简洁。

    由于某种原因,您需要更改一个或多个首选项在未来的存储方式,您只需在一处更改代码。

    对于通知名称,您可以向与通知关联的每个类添加常量。您可以在许多 iOS 类中看到这种模式,例如 UIApplication、UITextView 等。

    class SomeClass {
        static someClassEventNotification = NSNotification.Name("someUniqueName")
    }
    

    【讨论】:

    • 哇,我真的很喜欢你关于 UserDefaults 的建议,我喜欢它。
    • 如果我想将通知从 AppDelegate/applicationWillEnterForeground 类发送到我的主视图控制器类,我不确定如何使用您的方法来管理通知名称。您介意再详细说明一下吗?
    • 您不会为此使用自己的通知,也不会在应用程序委托中执行任何操作。只需让视图控制器注册现有的UIApplication.willEnterForegroundNotification 通知。
    • op 需要知道创建密钥的最佳方式,而不是创建数据存储方式
    • 在此答案中,操作问题与如何管理此private let highScoreKey = "highScore" 相关,而不是如何保存
    【解决方案2】:

    常用的方法是创建

    struct Constants { 
       static let key1 = "value1"
       static let key2 = "value2"
       .....
    }
    

    // 用于通知

    extension Notification.Name {
      static let didReceiveData = Notification.Name("didReceiveData")
      static let didCompleteTask = Notification.Name("didCompleteTask")
    }
    

    有些人更喜欢带有(k 字母前缀)的全局变量

    let kDomain = "value1"
    

    在 Objective-C 中的日期为 #define,但使用常量是一种简洁的代码阅读器方式

    【讨论】:

    • 建议很多。您介意告诉我您将如何使用该扩展程序吗?
    • 似乎有一个“远离”extension Notification.Name { 的举动,而是用它们的使用上下文来定义它们,例如UIApplication.willEnterForegroundNotification
    • @MadProgrammer 这适用于自定义通知名称,而不是你提到的
    • @Sh_Khan 不确定你的意思,但核心 API 似乎正在远离 Notification.Name 扩展并将它们放在使用它们的类上下文中,你为什么不遵循核心API 约定?
    • 我的回答并没有说 willEnterForegroundNotification 将用于应用程序中自定义通知键名称的扩展中
    【解决方案3】:

    我认为使用枚举来定义常量更合适

    用户默认值:

    class MyAppPreferences {
        static let shared = MyAppPreferences()
    
        private enum Key: String {
            case userName
            case email
        }
    
        var userName: String? {
            get {
                return UserDefaults.standard.string(forKey: Key.userName.rawValue)
            }
            set {
                UserDefaults.standard.set(newValue, forKey: Key.userName.rawValue)
            }
        }
    }
    

    通知:

    enum AppNotification: String {
        case didReceivedData
        case didCompleteTask
    }
    
    extension Notification.Name {
        init(_ appNotification:AppNotification) {
            self.init(appNotification.rawValue)
        }
    }
    
    //Use:
    
    func notify() {
        NotificationCenter.default.post(.init(name: .init(.didReceivedData)))
    } 
    

    【讨论】:

      猜你喜欢
      • 2017-01-04
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2021-12-09
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      相关资源
      最近更新 更多