为啥在 .addObserver 中以 NSException 类型的未捕获异常终止
Posted
技术标签:
【中文标题】为啥在 .addObserver 中以 NSException 类型的未捕获异常终止【英文标题】:Why terminating with uncaught exception of type NSException in .addObserver为什么在 .addObserver 中以 NSException 类型的未捕获异常终止 【发布时间】:2019-03-18 16:51:03 【问题描述】:我将使用UIAttachmentBehavior
将anchorPoint
连接到特定的UIView
,然后使用CAShapeLayer
画一条线。
我用addObserver
每分钟带上UIView
的坐标。
但是,发生未知错误。我想我不熟悉这个功能。
错误:
libc++abi.dylib: terminating with uncaught exception of type NSException
代码:
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController
private var animator: UIDynamicAnimator?
private var gravity: UIGravityBehavior?
private var attach: UIAttachmentBehavior?
private var plateView: UIView?
var lineLayer: CAShapeLayer?
override func loadView()
let view = UIView()
view.backgroundColor = .white
self.view = view
plateView = UIView(frame: CGRect(x: 80, y: 150, width: 60, height: 60))
plateView?.backgroundColor = UIColor.orange
self.view.addSubview(plateView!)
animator = UIDynamicAnimator(referenceView: view)
gravity = UIGravityBehavior(items: [plateView!])
animator?.addBehavior(gravity!)
attach = UIAttachmentBehavior(item: plateView!, offsetFromCenter: UIOffset(horizontal: 0, vertical: -30), attachedToAnchor: CGPoint(x: 200, y: 100))
attach?.damping = 0.1
attach?.frequency = 0.6
animator?.addBehavior(attach!)
plateView?.addObserver(self, forKeyPath: "center", options: .new, context: nil)
func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
updateLine()
func updateLine()
if nil == lineLayer
lineLayer = CAShapeLayer()
lineLayer?.strokeColor = UIColor.purple.cgColor
lineLayer?.fillColor = UIColor.clear.cgColor
lineLayer?.lineWidth = 1.5
lineLayer?.lineJoin = .round
lineLayer?.strokeEnd = 1.0
self.view.layer.addSublayer(lineLayer!)
let platePoint = view.convert(CGPoint(x: plateView!.bounds.midX, y: 0), from: plateView)
let bezierPath = UIBezierPath()
bezierPath.move(to: attach!.anchorPoint)
bezierPath.addLine(to: platePoint)
lineLayer?.path = bezierPath.cgPath
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
我查了资料,但是问题太全面了,找不到明确的答案。
我需要了解和理解这个问题的原因。为什么我的代码会出现这个问题?
为了您的信息,我正在关注this 文档的教程。
【问题讨论】:
您的observeValue(...)
和updateLine()
方法需要在loadView
之外定义
@dan 即使没有方法,代码仍然有错误。在我看来,错误的问题是.addObserver
。
我把你的代码粘贴到了一个操场上,然后移动了这两个方法,效果很好
@dan 谢谢!你的知识:)
【参考方案1】:
您需要将observeValueForKeyPath:ofObject:change:context
和updateLine
函数移出loadView()
函数。
observeValueForKeyPath:ofObject:change:context
函数需要在 ViewController 级别覆盖,因为您在 self
上添加了观察者,在本例中是视图控制器。
见下文:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController
private var animator: UIDynamicAnimator?
private var gravity: UIGravityBehavior?
private var attach: UIAttachmentBehavior?
private var plateView: UIView?
var lineLayer: CAShapeLayer?
override func loadView()
let view = UIView()
view.backgroundColor = .white
self.view = view
plateView = UIView(frame: CGRect(x: 80, y: 150, width: 60, height: 60))
plateView?.backgroundColor = UIColor.orange
self.view.addSubview(plateView!)
animator = UIDynamicAnimator(referenceView: view)
gravity = UIGravityBehavior(items: [plateView!])
animator?.addBehavior(gravity!)
attach = UIAttachmentBehavior(item: plateView!, offsetFromCenter: UIOffset(horizontal: 0, vertical: -30), attachedToAnchor: CGPoint(x: 200, y: 100))
attach?.damping = 0.1
attach?.frequency = 0.6
animator?.addBehavior(attach!)
plateView?.addObserver(self, forKeyPath: "center", options: .new, context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
updateLine()
func updateLine()
if nil == lineLayer
lineLayer = CAShapeLayer()
lineLayer?.strokeColor = UIColor.purple.cgColor
lineLayer?.fillColor = UIColor.clear.cgColor
lineLayer?.lineWidth = 1.5
lineLayer?.lineJoin = .round
lineLayer?.strokeEnd = 1.0
self.view.layer.addSublayer(lineLayer!)
let platePoint = view.convert(CGPoint(x: plateView!.bounds.midX, y: 0), from: plateView)
let bezierPath = UIBezierPath()
bezierPath.move(to: attach!.anchorPoint)
bezierPath.addLine(to: platePoint)
lineLayer?.path = bezierPath.cgPath
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
【讨论】:
感谢您的知识! :)以上是关于为啥在 .addObserver 中以 NSException 类型的未捕获异常终止的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能在 react native 中以编程方式添加道具?