我需要某些类型的系统信息来配置我的应用。我想通过有一个模型类来实现此目的,以使信息可用。我知道如何获取所需的信息,但是我正努力将收集到的信息存储在模型类的属性中。
我希望能够:
let sysInfoModel = SysInfoModel()
let installedOsVersion = sysInfoModel.osVersion
应从需要设置此信息的vieController实例化模型类。 我认为我的全部尝试都是错误的,以实现这种目标。这样做的正确方法是什么?
class SysInfoModel {
// Properties
let macModel: String?
let osVersion: String?
// Initialization
init() {
if let actualModel = getMacModel() { //ERROR: 'self' used in method call 'getMacModel' before all stored properties are initialized
self.macModel = actualModel
} else {
macModel = "Hardware model not found"
}
if let actualOsVersion = getOsVersion() { // ERROR: 'self' used in method call 'getOsVersion' before all stored properties are initialized
osVersion = actualOsVersion
} else {
osVersion = "OS Version not available"
}
}
// Returns the hardware model identifier as a string
func getMacModel() -> String? {
var modelIdentifier: String?
let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
if let modelData = IORegistryEntryCreateCFProperty(service, "model" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data {
modelIdentifier = String(data: modelData, encoding: .utf8)
}
IOObjectRelease(service)
return modelIdentifier
}
// Returns the OS Version as a String
func getOsVersion() -> String? {
let osVersion: OperatingSystemVersion = ProcessInfo.processInfo.operatingSystemVersion
let osVersionString = String("\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)")
return osVersionString
}
}
根据马特的回答进行更新:
// Properties
var askSystem: AskTheSystem
let macModel: String?
let osVersion: String?
init() {
askSystem = AskTheSystem()
if let actualModel = askSystem.getMacModel() {
self.macModel = actualModel
} else {
macModel = "Hardware model not found"
}
if let actualOsVersion = askSystem.getOsVersion() {
osVersion = actualOsVersion
} else {
osVersion = "OS Version not available"
}
}
我做到了,可以将功能getMacModel()
和getOsVersion()
放在一个单独的类AskTheSystem
中。在SysInfoModel
中实例化它。
可行,但这是一个好习惯吗?我看不到只为那些功能添加另一个类的意义吗?这样做的正确方法是什么?
答案 0 :(得分:0)
我同意马特,正确是一种判断。
一个合理的解决方案是延迟实例化的属性,第一次访问该属性时,一次都会检索这两个值
class SysInfoModel {
// Returns the hardware model identifier as a string
lazy var macModel : String = {
let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
defer{IOObjectRelease(service)}
guard let modelData = IORegistryEntryCreateCFProperty(service, "model" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data else {
return "Hardware model not found"
}
return String(data: modelData, encoding: .utf8)!
}()
// Returns the OS Version as a String
lazy var osVersion : String = {
let osVersion = ProcessInfo.processInfo.operatingSystemVersion
return "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
}()
}