我有一个快速的自定义CALayer,它有一些动态(实际@NSManaged
属性)我已正确设置所有内容并且正在调用图层actionForKey。
override public func actionForKey(key: String!) -> CAAction! {
switch key {
case "maxCircles", "numCircles":
let animation = CABasicAnimation(keyPath: key)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear);
animation.fromValue = self.presentationLayer().valueForKey(key);
animation.duration = 0.2
return animation;
default:
return super.actionForKey(key)
}
}
有时self.presentationLayer().
会抛出异常,因为它是隐式展开的,并且是nil。在Objective-C中,代码通常只是:
[[self presentationLayer] valueForKey:key]
哪个没有崩溃,但我从未意识到它可以调用nil并生成0 - 这对我来说感觉非常错误。我无法保证我的动画来自无。
在Swift中访问presentationLayer
的正确方法是什么?我应该测试零吗?即:
override public func actionForKey(key: String!) -> CAAction! {
if ( key == "maxCircles" || key == "numCircles" ) && self.presentationLayer() != nil {
let animation = CABasicAnimation(keyPath: key)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear);
animation.fromValue = self.presentationLayer().valueForKey(key);
animation.duration = 0.2
return animation;
}
return super.actionForKey(key)
}
答案 0 :(得分:1)
presentationLayer
属性返回一个可选项,所以是的,你应该测试nil。在Objective-C消息传递中,nil是一个无操作,因此不会导致您的应用程序崩溃。请记住,安全是swift的主要目标之一,因此您需要在此处进行自己的检查。如果你编写这样的函数,它的工作方式与Objective-C相似:
override public func actionForKey(key: String!) -> CAAction! {
if key == "maxCircles" || key == "numCircles" {
// Check your presentation layer first before doing anything else
if let presoLayer = self.presentationLayer() as? CALayer {
let animation = CABasicAnimation(keyPath: key)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear);
animation.fromValue = presoLayer.valueForKey(key);
animation.duration = 0.2
return animation;
}
}
return super.actionForKey(key)
}
我假设您的其余代码就在这里,只是回答有关presentationLayer
可选性的部分。我将您的switch
切换为if
,因为它对我来说似乎更具可读性。
答案 1 :(得分:1)
Matt Long的解决方案有效。但是,如果您希望保留switch
语法,则可以使用nil
语法测试case … where
:
override func actionForKey(key: String!) -> CAAction! {
switch key {
case "maxCircles", "numCircles" where self.presentationLayer() != nil:
let animation = CABasicAnimation(keyPath: key)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear);
animation.fromValue = self.presentationLayer().valueForKey(key);
animation.duration = 0.2
return animation;
default:
return super.actionForKey(key)
}
}
或者,如果没有表示层,您可以提供默认fromValue
:
animation.fromValue = self.presentationLayer() != nil ? self.presentationLayer().valueForKey(key) : 0;