swift中的类的属性列表 [英] List of class's properties in swift
问题描述
注意:在这里上发布了一个类似的问题,
我有一个在swift中声明的类,像这样:
import UIKit
class EachDayCell:UITableViewCell
{
@IBOutlet var dateDisplayLabel:UITextField
@IBOutlet var nameDisplayLabel:UITextField
@IBAction func goToPendingItems(sender:AnyObject){
}
@IBAction func showDateSelectionPicker(sender:AnyObject){
}
init(style:UITableViewCellStyle,reuseIdentifier:String!)
{
super.init(style:style,reuseIdentifier:reuseIdentifier)
}
}
现在我想在swift中获取一个数组:dateDisplayLabel,nameDisplayLabel。
如何实现这一点?
使用镜像
这是一个纯Swift解决方案,有一些限制:
PropertyNames {
func propertyNames() - > [String]
}
扩展PropertyNames
{
func propertyNames() - > [String] {
return Mirror(reflect:self).children.flatMap {$ 0.label}
}
}
class Person:PropertyNames {
var name =Sansa Stark
var awesome = true
}
Person()。propertyNames()// [name,awesome]
限制:
- 返回Objective-C对象的空数组
-
不返回计算属性,例如:
var favoriteFood:String {returnLemon Cake}
-
code> self 是一个类的实例(vs.,比如说,一个struct),这不会报告它的超类的属性,例如:
class Person:PropertyNames {
/ pre>
var name =Bruce Wayne
}
class Superhero:Person {
var hasSuperpowers = true
}
Superhero()。propertyNames()// [hasSuperpowers] - 无名称
您可以使用
/ li>superclassMirror()
解决这个问题,具体取决于您的期望行为。
使用 class_copyPropertyList
如果你使用Objective-C对象,你可以使用这种方法:
var count = UInt32 b let classToInspect = NSURL.self
让属性:UnsafeMutablePointer< objc_property_t> = class_copyPropertyList(classToInspect,& count)
var propertyNames = [String]()
let intCount = Int(count)
for var i = i< intCount; i ++ {
let property:objc_property_t = properties [i]
guard let propertyName = NSString(UTF8String:property_getName(property))as? String else {
debugPrint(无法解开\(属性)的属性名称)
break
}
propertyNames.append(propertyName)
}
free(properties)
print(propertyNames)
如果 classToInspect
是 NSURL
:
的输出到控制台
这不会在游乐场工作。只需用 NSURL
替换 EachDayCell
(或重用相同的逻辑作为扩展),它应该工作。
Note: there is a similar question posted for objective c over here, but I want to achieve it in swift.
I have a class declared in swift like this:
import UIKit
class EachDayCell : UITableViewCell
{
@IBOutlet var dateDisplayLabel : UITextField
@IBOutlet var nameDisplayLabel : UITextField
@IBAction func goToPendingItems(sender : AnyObject) {
}
@IBAction func showDateSelectionPicker(sender : AnyObject) {
}
init(style: UITableViewCellStyle, reuseIdentifier: String!)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
}
Now I want to get an array in swift enlisting: dateDisplayLabel, nameDisplayLabel.
How can I achieve this?
Using Mirror
Here's a pure Swift solution with some limitations:
protocol PropertyNames {
func propertyNames() -> [String]
}
extension PropertyNames
{
func propertyNames() -> [String] {
return Mirror(reflecting: self).children.flatMap { $0.label }
}
}
class Person : PropertyNames {
var name = "Sansa Stark"
var awesome = true
}
Person().propertyNames() // ["name", "awesome"]
Limitations:
- Returns an empty array for Objective-C objects
Will not return computed properties, i.e.:
var favoriteFood: String { return "Lemon Cake" }
If
self
is an instance of a class (vs., say, a struct), this doesn't report its superclass's properties, i.e.:class Person : PropertyNames { var name = "Bruce Wayne" } class Superhero : Person { var hasSuperpowers = true } Superhero().propertyNames() // ["hasSuperpowers"] — no "name"
You could work around this using
superclassMirror()
depending on your desired behavior.
Using class_copyPropertyList
If you're using Objective-C objects you can use this approach:
var count = UInt32()
let classToInspect = NSURL.self
let properties : UnsafeMutablePointer <objc_property_t> = class_copyPropertyList(classToInspect, &count)
var propertyNames = [String]()
let intCount = Int(count)
for var i = 0; i < intCount; i++ {
let property : objc_property_t = properties[i]
guard let propertyName = NSString(UTF8String: property_getName(property)) as? String else {
debugPrint("Couldn't unwrap property name for \(property)")
break
}
propertyNames.append(propertyName)
}
free(properties)
print(propertyNames)
The output to the console if classToInspect
is NSURL
:
["pathComponents", "lastPathComponent", "pathExtension", "URLByDeletingLastPathComponent", "URLByDeletingPathExtension", "URLByStandardizingPath", "URLByResolvingSymlinksInPath", "dataRepresentation", "absoluteString", "relativeString", "baseURL", "absoluteURL", "scheme", "resourceSpecifier", "host", "port", "user", "password", "path", "fragment", "parameterString", "query", "relativePath", "hasDirectoryPath", "fileSystemRepresentation", "fileURL", "standardizedURL", "filePathURL"]
This won't work in a playground. Just replace NSURL
with EachDayCell
(or reuse the same logic as an extension) and it should work.
这篇关于swift中的类的属性列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!