Realm中更新版本值的代码重复优化方案咨询
Hey there! Let's fix that code duplication in your Realm version update logic. The core issue here is that each versioned class (like VersionY and VersionX) is repeating the same Realm write operation boilerplate. Here are a couple of clean approaches to eliminate that repetition:
Option 1: Use a Protocol with Default Implementation (Type-Safe & Object-Oriented)
We can define a protocol that outlines the required info for each versioned class, then add a default implementation of the update method via an extension. This keeps each class responsible for its own version details while reusing the common update logic.
First, define the protocol (we'll use Swift KeyPaths for type safety instead of string KVC, to avoid typos):
protocol VersionUpdatable: Object { // The key path to the corresponding version property in your Versions class static var versionKeyPath: WritableKeyPath<Versions, Int> { get } // The latest version number for this class static var currentVersion: Int { get } }
Then add the default update logic to the protocol extension:
extension VersionUpdatable { func updateStoredVersion(versions: Versions) -> Bool { do { try LocalFilesManager.realm.write { // Use the key path to set the correct version property versions[keyPath: Self.versionKeyPath] = Self.currentVersion } return true } catch { print("Failed to update version: \(error.localizedDescription)") return false } } }
Now your versioned classes just need to conform to the protocol and provide their specific details—no more repeating the write logic!
class VersionY: VersionUpdatable { static let versionKeyPath: WritableKeyPath<Versions, Int> = \.versionY static let currentVersion = 1 // Replace with your actual latest version // Your existing VersionY properties/logic here } class VersionX: VersionUpdatable { static let versionKeyPath: WritableKeyPath<Versions, Int> = \.versionX static let currentVersion = 2 // Replace with your actual latest version // Your existing VersionX properties/logic here }
Option 2: Create a Reusable Version Manager Utility Class
If you prefer a more centralized approach, you can extract the update logic into a dedicated utility class. This is great if you want to handle additional cross-cutting concerns (like logging or error handling) in one place.
class VersionManager { static func updateVersion(for keyPath: WritableKeyPath<Versions, Int>, to version: Int, in versions: Versions) -> Bool { do { try LocalFilesManager.realm.write { versions[keyPath: keyPath] = version } return true } catch { print("Version update failed: \(error.localizedDescription)") return false } } }
Then call this utility method from your versioned classes:
class VersionY: Object { private static let versionKeyPath = \Versions.versionY private static let currentVersion = 1 func updateStoredVersion(versions: Versions) -> Bool { return VersionManager.updateVersion(for: Self.versionKeyPath, to: Self.currentVersion, in: versions) } // Your existing VersionY properties/logic here }
Why These Work
- Both approaches eliminate duplicate Realm write boilerplate.
- Using KeyPaths instead of string KVC ensures type safety—you’ll get a compile error if you reference a non-existent property on
Versions, instead of a runtime crash. - The protocol approach keeps each class’s version info encapsulated, while the utility class centralizes the update logic for easier maintenance.
内容的提问来源于stack exchange,提问作者NoKey

