Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何获取节点';属性的键路径的s值';s属性_Swift_Properties_Key - Fatal编程技术网

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