Swift 镜像反射不返回 UIVIew 上的属性

Swift Mirror reflection not returning properties on UIVIew

正在尝试通过以下方式获取 UIView 或 UIViewController 的所有属性:

func propertysNames()->[String]{
    var s = [String]()
    for c in Mirror(reflecting: self).children
    {
        if let name = c.label{
            s.append(name)
        }
    }
    return s
}

这适用于 UIVIewController,但 UIView 似乎没有 return 属性,有什么建议吗?

import UIKit

let viewController = UIViewController()
let view = UIView()
class MyViewController: UIViewController {
    let i = 1
    let myView = MyView()
}
class MyView : UIView {
    let label = UILabel()
    let i = 1
}

Mirror(reflecting: MyViewController()).children.count   // 2
Mirror(reflecting: MyView()).children.count             // 0

你说得对!只需填写错误报告 ...

或者是蓄意破坏,因为我发现了这个

extension UIView : _Reflectable {
}

不确定您要实现的目标,但 UIView 继承了 NSObject。正因为如此,您可以随意支配 objc 运行 的大部分时间。因此,作为替代方案,您可以执行以下操作:

import UIKit

extension NSObject {
  func propertysNames() -> [String]{
    var count : UInt32 = 0
    let classToInspect = self.dynamicType
    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]
      let propertyName = NSString(UTF8String: property_getName(property))!
      propertyNames.append(propertyName as String)
    }
    free(properties)
    return propertyNames
  }
}

print(UIView().propertysNames())
// prints: "["_mayRemainFocused", "_sensitivitySize", "skipsSubviewEnumeration", "viewTraversalMark", "viewDelegate", "monitorsSubtree", "backgroundColorSystemColorName", "currentScreenScale", "maskView", "_userInterfaceIdiom", "hash", "superclass", "description", "debugDescription", "gesturesEnabled", "deliversTouchesForGesturesToSuperview", "deliversButtonsForGesturesToSuperview", "_shouldReverseLayoutDirection", "leadingAnchor", "trailingAnchor", "leftAnchor", "rightAnchor", "topAnchor", "bottomAnchor", "widthAnchor", "heightAnchor", "centerXAnchor", "centerYAnchor", "firstBaselineAnchor", "lastBaselineAnchor", "_keyboardOrientation", "_touchForceObservable", "_inheritedRenderConfig", "_lightStyleRenderConfig", "_accessoryViewFrame", "unsatisfiableConstraintsLoggingSuspended", "hash", "superclass", "description", "debugDescription", "hash", "superclass", "description", "debugDescription", "userInteractionEnabled", "tag", "layer", "focused", "semanticContentAttribute", "interactionTintColor", "_layoutDebuggingIdentifier", "_countOfMotionEffectsInSubtree", "_maskView", "_ancestorDefinesTintColor", "_ancestorDefinesTintAdjustmentMode", "_presentationControllerToNotifyOnLayoutSubviews", "_rawLayoutMargins", "_inferredLayoutMargins", "_dontUpdateInferredLayoutMargins", "_tracksFocusedAncestors", "_countOfFocusedAncestorTrackingViewsInSubtree", "_mutableLayoutGuides", "_mutableLayoutArrangements", "_hiddenManagedByLayoutArrangementCount", "_pendingHiddenCount", "previewingSegueTemplateStorage", "_continuousCornerRadius", "_canBeParentTraitEnviroment", "_layoutEngine", "_boundsWidthVariable", "_boundsHeightVariable", "_minXVariable", "_minYVariable", "_internalConstraints", "_constraintsExceptingSubviewAutoresizingConstraints", "unsatisfiableConstraintsLoggingSuspended", "_shouldArchiveUIAppearanceTags", "_interactionTintColor", "_backdropMaskViewForGrayscaleTint", "_backdropMaskViewForColorTint", "_backdropMaskViewForFilters", "_backdropMaskViews", "_wantsGeometryChangeNotification", "contentSizeNotificationToken", "layoutMarginsGuide", "readableContentGuide", "hash", "superclass", "description", "debugDescription", "traitCollection", "preferredFocusedView", "center", "bounds", "transform", "collisionBoundsType", "collisionBoundingPath"]\n"

此外,我确实看到将您的代码应用于 UIKit 对象时有些奇怪。不确定导致它失败的变量是什么。它似乎适用于 Swift:

中编写的 NSObject 类型
import UIKit

class Fruit {
  var type=1
  var name="Apple"
  var delicious=true
}

var s = [String]()
for c in Mirror(reflecting: Fruit()).children
{
  if let name = c.label{
    s.append(name)
  }
}

print(s)
// works: "["type", "name", "delicious"]\n"

class FruitNSObject: NSObject {
  var type:NSNumber=1
  var name:NSString="Apple"
  var delicious=true
}

s = [String]()
for c in Mirror(reflecting: FruitNSObject()).children
{
  if let name = c.label {
    s.append(name)
  }
}

print(s)
// works: "["type", "name", "delicious"]\n"

s = [String]()
for c in Mirror(reflecting: UIView()).children
{
  if let name = c.label {
    s.append(name)
  }
}

print(s)
// doesn't work: "[]\n"

s = [String]()
for c in Mirror(reflecting: UIViewController()).children
{
  if let name = c.label {
    s.append(name)
  }
}

print(s)
// doesn't work: "[]\n"

所以这是一个错误,或者在 Swift 当前版本的 Swift <-> ObjC 中存在一些限制。也许这与@user3441734 在他的回答中指出的内容有关。

顺便说一句,所有代码都是 运行 在操场上 Xcode(即 7.1.1)的最新版本。