Swift 如何获取节点';属性的键路径的s值';s属性
我希望获取属性属性的键路径的值,例如Swift 如何获取节点';属性的键路径的s值';s属性,swift,properties,key,Swift,Properties,Key,我希望获取属性属性的键路径的值,例如size.width或position.x的值(对于SKSpriteNode)。如果我在SKScene中有以下代码,我会在最后一行得到一个运行时错误: let sprite = SKSpriteNode() sprite.color = SKColor.red sprite.size = CGSize(width: 50, height: 50) sprite.position = CGPoint(x: 320, y: 240) self.addChild(
size.width
或position.x
的值(对于SKSpriteNode
)。如果我在SKScene
中有以下代码,我会在最后一行得到一个运行时错误:
let sprite = SKSpriteNode()
sprite.color = SKColor.red
sprite.size = CGSize(width: 50, height: 50)
sprite.position = CGPoint(x: 320, y: 240)
self.addChild(sprite)
print(sprite.value(forKeyPath: "position")) //NSPoint: {320, 204}
print(sprite.value(forKeyPath: "size")) //NSSize: {50,50}
print(sprite.value(forKeyPath: "position.x")) //terminating with uncaught exception of type NSException
在Swift 4中有没有这样做的方法?感谢您的帮助,并提前表示感谢
编辑:
下面是另一个不起作用的例子:
class Object: NSObject {
var foo : Foo = Foo()
}
class Foo : NSObject {
var bar : Int = 0
}
let myObject = Object()
print(myObject.foo.bar) //0
print(myObject.value(forKeyPath: "foo.bar")) //terminating with uncaught exception of type NSException
我明白我可以像@Eric在我的第一个例子中所说的那样:
print((sprite.value(forKeyPath: "position") as! CGPoint).x) //works fine
但这在我的第二个示例中不起作用:
print((myObject.value(forKeyPath: "foo") as! Foo).bar) //still terminating with uncaught exception of type NSException
这使我相信这是一个“黑客”不会一直工作,所以我不希望使用它。通过对这个主题的进一步研究,我发现了这个目标C代码,它表明value forKeyPath的全部要点是能够获得属性的属性:
// Using nested valueForKey:
NSLog(@"%@", [[myObject valueForKey:@"foo"] valueForKey:@"bar"]);
// Can be done with a single valueForKeyPath;
NSLog(@"%@", [myObject valueForKeyPath:@"foo.bar"]);
如果我将其转换为swift,我会得到:
// Using nested valueForKey:
print(myObject.value(forKey: "foo").value(forKey: "bar")) //Error: value of 'Any?' has no member 'value'
// Can be done with a single valueForKeyPath;
print(myObject.value(forKeyPath: "foo.bar")) //terminating with uncaught exception of type NSException
轻松修复第二行:
// Using nested valueForKey:
print((myObject.value(forKey: "foo") as! Foo).value(forKey: "bar")) //terminating with uncaught exception of type NSException
// Can be done with a single valueForKeyPath;
print(myObject.value(forKeyPath: "foo.bar")) //also terminating with uncaught exception of type NSException
但现在它们都显示了错误,这让我相信这可能是值forKeyPath和值forKey没有正确地实现到swift中。如果有人能提供一点激励,这将非常有帮助。最后一行行不通,因为现在正手时“位置”将是一个带有
x
值的NSPoint
。要使其工作,只需将该位置转换为CGPoint/NSPoint
,如下所示:
print((sprite.value(forKeyPath: "position") as! CGPoint).x)
然而,解释标记所做的硬铸造并不是一个好主意,因为当精灵没有设置位置时,它会崩溃,所以最好使用:
if let position = sprite.value(forKeyPath: "position") as? CGPoint {
print(position.x)
}
关于编辑部分 通过KVC(基于字符串的键路径使用KVC)访问的所有属性都需要公开给Objective-C运行时。在Swift 4中,需要使用
@objc
显式注释
class Object: NSObject {
@objc var foo : Foo = Foo() //<-
}
class Foo : NSObject {
@objc var bar : Int = 0 //<-
}
let myObject = Object()
print(myObject.foo.bar) //->0
print(myObject.value(forKeyPath: "foo.bar")) //->Optional(0)
print((myObject.value(forKey: "foo") as! Foo).value(forKey: "bar")) //->Optional(0)
print((myObject.value(forKeyPath: "foo") as! Foo).bar) //->0
智能键路径不是基于字符串的键路径的另一种表示法,因此它不能取代KVC键路径的所有用例。但它可以用于非目标C属性,这在某些情况下非常方便。谢谢,但虽然这在我的示例中有效,但并非在所有情况下都有效,我在问题的编辑中添加了一个不起作用的示例。这正是我要找的。你帮了这么多忙,谢谢!这使一切变得容易了10倍。我有一个关于这些智能钥匙路径的问题,但我认为它超出了这个问题的范围,所以我做了一个新的。你似乎对此很了解,也许你可以回答:
let sprite = SKSpriteNode()
sprite.color = SKColor.red
sprite.size = CGSize(width: 50, height: 50)
sprite.position = CGPoint(x: 320, y: 240)
print(sprite[keyPath: \SKSpriteNode.position]) //->(320.0, 240.0)
print(sprite[keyPath: \SKSpriteNode.size]) //->(50.0, 50.0)
print(sprite[keyPath: \SKSpriteNode.position.x]) //->320.0