我有一个名为User()的类
class User {
var name: String?
var email: String?
var id: String?
var identification_number: String?
var phone_number: NSMutableArray?
var user_group: String?
var date: NSDate?
}
我想得到类中的所有变量及其各自的值。在这种情况下,我试图使用Mirror。
func updateProfile(user: User) {
let mirror = Mirror(reflecting: user)
for child in mirror.children {
print("\(child.label!), \(child.value)")
}
}
我的问题是,我如何将child.value
转换为任何其他数据类型,比如String
?我只需要知道child.value是属于child.value的
发布于 2016-01-06 17:39:48
创建一个扩展Optional<Any>
类型以返回它的非可选值的协议:
private protocol AnyOptional {
var objectValue: Any? { get }
}
extension Optional: AnyOptional {
var objectValue: Any? {
switch self {
case .None:
return nil
case .Some(_):
return self! as Any
}
}
}
此后,您可以使用AnyOptional
协议作为类型,并将Any?
对象转换为AnyOptional
,然后允许我们使用AnyOptional
的.objectValue
属性。
class User {
var name: String?
var email: String?
var id: String = "Default ID" // Lets try also with one non-optional
var identification_number: String?
var phone_number: NSMutableArray?
var user_group: String?
var date: NSDate?
}
var myUser = User()
myUser.name = "John"
myUser.phone_number = ["+44", "701 23 45 67"]
func updateProfile(user: User) {
let mirror = Mirror(reflecting: user)
for child in mirror.children {
let value : Any = (child.value as? AnyOptional)?.objectValue ?? child.value
switch(value) {
case let obj as String: print("String item: User.\(child.label!) = " + obj)
case let obj as NSMutableArray: print("NSMutableArray item: User.\(child.label!) = \(obj)")
case let obj as NSDate: print("NSDate item: User.\(child.label!) = \(obj)")
case _ : print("Non-initialized optional item: User.\(child.label!) = \(value)")
}
}
}
,它产生以下输出
updateProfile(myUser)
/*
String item: User.name = John
Non-initialized optional item: User.email = nil
String item: User.id = Default ID
Non-initialized optional item: User.identification_number = nil
NSMutableArray item: User.phone_number = (
"+44",
"701 23 45 67"
)
Non-initialized optional item: User.user_group = nil
Non-initialized optional item: User.date = nil */
使用此解决方案的好处是,它将“解包”child.value
的可选非零值(没有"Optional(...)"
填充)以及非可选的child.value
值,而不需要对这两种情况分别进行“展开”。在上面的switch
案例中,您可以处理需要处理的User
对象的任何非零属性,不仅作为String
,还可以处理User
类中的任何类型。obj
属性在switch
中将是类的每个非零属性的非可选类型。默认情况对应于值nil
(未指定)的选项。
发布于 2016-01-06 15:36:33
child.value
具有Any
类型。从Any
到可选的转换会带来一些问题,幸运的是桑迪·查普曼在this post中给出了一个很好的解决方案。
使用他的函数,代码将如下所示:
func castToOptional<T>(x: Any) -> T? {
return Mirror(reflecting: x).descendant("Some") as? T
}
func updateProfile(user: User) {
let mirror = Mirror(reflecting: user)
for child in mirror.children {
print("\(child.label!), \(child.value)")
if let stringVal = castToOptional(child.value) as String? {
print("Unwrapped a string: \(stringVal)")
} else if let stringVal = child.value as? String {
print("Found a non-optional string: \(stringVal)")
}
}
}
因此,如果要查找字符串,则需要同时查找可选和非可选字符串。这适用于您需要检查的所有类型。
https://stackoverflow.com/questions/34636854
复制相似问题