swift中的类的属性列表 [英] List of class's properties in swift

查看:260
本文介绍了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 {
    var name =Bruce Wayne
    }

    class Superhero:Person {
    var hasSuperpowers = true
    }

    Superhero()。propertyNames()// [hasSuperpowers] - 无名称
    / pre>

    您可以使用 superclassMirror()解决这个问题,具体取决于您的期望行为。

    / li>


使用 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


的输出到控制台 绝对路径,ativeString,baseURL,absoluteURL,scheme,resourceSpecifier,host,port,user,password ,query,relativePath,hasDirectoryPath,fileSystemRepresentation,fileURL,standardizedURL,filePathURL]


这不会在游乐场工作。只需用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆