Ответ 1
Использование Mirror
Здесь чистое решение Swift с некоторыми ограничениями:
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"]
Ограничения:
- Возвращает пустой массив для объектов Objective-C
-
Не возвращать вычисленные свойства, т.е.:
var favoriteFood: String { return "Lemon Cake" }
-
Если
self
- это экземпляр класса (vs., скажем, struct), это не сообщает о его свойствах суперкласса, то есть:class Person : PropertyNames { var name = "Bruce Wayne" } class Superhero : Person { var hasSuperpowers = true } Superhero().propertyNames() // ["hasSuperpowers"] — no "name"
Вы можете обойти это, используя
superclassMirror()
в зависимости от вашего желаемого поведения.
Использование class_copyPropertyList
Если вы используете объекты Objective-C, вы можете использовать этот подход:
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)
Выход на консоль, если classToInspect
равен 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"]
Это не будет работать на игровой площадке. Просто замените NSURL
на EachDayCell
(или повторите ту же логику, что и расширение), и он должен работать.