Non optional IBOutlet returns Fatal error: when referenced from another UIViewController class
Non optional IBOutlet returns Fatal error: when referenced from another UIViewController class
我在
中定义了一个 UIView
class InteractViewController: UIViewController {
@IBOutlet weak var tipsView: UIView!
var tipslayer: CALayer {
return tipsView.layer
}
}
class 中还附加了一些约束以及标签。
@IBOutlet weak var tips1Top: NSLayoutConstraint!
@IBOutlet weak var tips1Right: NSLayoutConstraint!
@IBOutlet weak var tipsTitle: UILabel!
@IBOutlet weak var tipsDesc: UILabel!
所有人都在故事板上连接到正确的出口。在实际的 InteractViewController 本身中引用这些我能够调整不透明度,更新层上的标签等
但是,除非用户第一次使用该应用程序,否则不需要这些,因此在 InteractViewController 上调用一个函数来显示和更新这些属性或根本不显示它们。
控制和更新这些属性的函数在调用的项目中的另一个class(Swift文件中。
class TipsViewController: UIViewController {
func tips() {
InteractViewController().tipslayer.transform = CATransform3DMakeScale(0.8, 0.8, 1.0)
}
}
导致应用崩溃创建
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
在
return tipsView.layer (the InteractViewController)
tipsView 和 tipslayer 不是可选的,也没有声明为可选的。
我有三个问题希望得到帮助。
对 ViewController class InteractViewController: UIViewController 上的插座的物理引用是否有问题?如果是这样,是因为它们应该以编程方式添加,而不是在 class TipsViewController: UIViewController(在 Xcode 中没有物理视觉视图控制器) ?
是否对
上的网点有物理参考
class 互动ViewController:UIViewController
如果在 InteractViewController 上调用第二个 ViewContoller 上的函数 TipsViewController.tips() 从未被调用,则创建不必要的内存使用,换句话说,问题 1 的答案基本上是任何物理插座应该以编程方式在 lass 上添加 TipsViewController: UIViewController?
- 如果没有内存问题并且知道 tipsView 和返回的 tipslayer 不是可选的,为什么我根本无法从另一个 class 的 tips() 函数中引用它们(TipsViewController: UIViewController)?我看过很多关于 "passing data between view controllers" 的帖子,但我没有在变量或数组之间传递数据。我想/需要简单地更新标签字符串,约束(一个视图控制器class中的对象来自另一个视图控制器class。
我知道人们很忙,所以提前说一下,感谢所有反馈和对问题的帮助。
有人建议我的问题与 [
重复
但这不是我的问题。我的问题具体涉及从另一个 ViewController 访问一个 Outlet,然后生成对 Outlet 的 Nil 响应,因为正如解释的那样,InteractViewController 显然没有引用 ViewController。请阅读 Rob 提供的回答此特定问题的解释和答案。
您的标题是 "IBOutlet returns Fatal error: when referenced from another UIViewController class"。底线是一个视图控制器不应该访问另一个视图控制器的出口。
在您的代码片段中,您使用了 InteractViewController()
语法。不幸的是,这只是实例化视图控制器,但没有连接故事板中的插座。您需要通过故事板进行实例化,即便如此,您也不能立即引用您的 outlet,只能在稍后调用 viewDidLoad
之后。无论如何,只有视图控制器本身应该尝试访问它自己的插座。
TipsViewController()
或 InteractViewController()
语法表示 "create a new, blank instance of that view controller"。这相当于说 TipsViewController.init()
或 InteractViewController.init()
。而且,更糟糕的是,它根本没有使用故事板(因此不会连接任何插座)。那不是你想要的。您应该避免使用这种 ViewController()
语法,因为这样就永远无法访问出口。
InteractViewController
应确定是否应显示 TipsViewController
(例如检查用户默认值),如果是,则显示它。但是,InteractViewController
唯一应该做的是:
- 判断是否要呈现
TipsViewController
;
- 如果是,请提出
TipsViewController
;和
- 将模型数据(例如
InteractViewController
从 UserDefaults
检索到的任何内容)传递给为您创建的 TipsViewController
实例。
但是关于 TipsViewController
如何呈现其子视图的任何事情,都是 TipsViewController
的权限。 InteractViewController
不应直接与 TipsViewController
的任何媒体互动。
我在
中定义了一个 UIViewclass InteractViewController: UIViewController {
@IBOutlet weak var tipsView: UIView!
var tipslayer: CALayer {
return tipsView.layer
}
}
class 中还附加了一些约束以及标签。
@IBOutlet weak var tips1Top: NSLayoutConstraint!
@IBOutlet weak var tips1Right: NSLayoutConstraint!
@IBOutlet weak var tipsTitle: UILabel!
@IBOutlet weak var tipsDesc: UILabel!
所有人都在故事板上连接到正确的出口。在实际的 InteractViewController 本身中引用这些我能够调整不透明度,更新层上的标签等
但是,除非用户第一次使用该应用程序,否则不需要这些,因此在 InteractViewController 上调用一个函数来显示和更新这些属性或根本不显示它们。
控制和更新这些属性的函数在调用的项目中的另一个class(Swift文件中。
class TipsViewController: UIViewController {
func tips() {
InteractViewController().tipslayer.transform = CATransform3DMakeScale(0.8, 0.8, 1.0)
}
}
导致应用崩溃创建
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
在
return tipsView.layer (the InteractViewController)
tipsView 和 tipslayer 不是可选的,也没有声明为可选的。
我有三个问题希望得到帮助。
对 ViewController class InteractViewController: UIViewController 上的插座的物理引用是否有问题?如果是这样,是因为它们应该以编程方式添加,而不是在 class TipsViewController: UIViewController(在 Xcode 中没有物理视觉视图控制器) ?
是否对
上的网点有物理参考class 互动ViewController:UIViewController
如果在 InteractViewController 上调用第二个 ViewContoller 上的函数 TipsViewController.tips() 从未被调用,则创建不必要的内存使用,换句话说,问题 1 的答案基本上是任何物理插座应该以编程方式在 lass 上添加 TipsViewController: UIViewController?
- 如果没有内存问题并且知道 tipsView 和返回的 tipslayer 不是可选的,为什么我根本无法从另一个 class 的 tips() 函数中引用它们(TipsViewController: UIViewController)?我看过很多关于 "passing data between view controllers" 的帖子,但我没有在变量或数组之间传递数据。我想/需要简单地更新标签字符串,约束(一个视图控制器class中的对象来自另一个视图控制器class。
我知道人们很忙,所以提前说一下,感谢所有反馈和对问题的帮助。
有人建议我的问题与 [
但这不是我的问题。我的问题具体涉及从另一个 ViewController 访问一个 Outlet,然后生成对 Outlet 的 Nil 响应,因为正如解释的那样,InteractViewController 显然没有引用 ViewController。请阅读 Rob 提供的回答此特定问题的解释和答案。
您的标题是 "IBOutlet returns Fatal error: when referenced from another UIViewController class"。底线是一个视图控制器不应该访问另一个视图控制器的出口。
在您的代码片段中,您使用了 InteractViewController()
语法。不幸的是,这只是实例化视图控制器,但没有连接故事板中的插座。您需要通过故事板进行实例化,即便如此,您也不能立即引用您的 outlet,只能在稍后调用 viewDidLoad
之后。无论如何,只有视图控制器本身应该尝试访问它自己的插座。
TipsViewController()
或 InteractViewController()
语法表示 "create a new, blank instance of that view controller"。这相当于说 TipsViewController.init()
或 InteractViewController.init()
。而且,更糟糕的是,它根本没有使用故事板(因此不会连接任何插座)。那不是你想要的。您应该避免使用这种 ViewController()
语法,因为这样就永远无法访问出口。
InteractViewController
应确定是否应显示 TipsViewController
(例如检查用户默认值),如果是,则显示它。但是,InteractViewController
唯一应该做的是:
- 判断是否要呈现
TipsViewController
; - 如果是,请提出
TipsViewController
;和 - 将模型数据(例如
InteractViewController
从UserDefaults
检索到的任何内容)传递给为您创建的TipsViewController
实例。
但是关于 TipsViewController
如何呈现其子视图的任何事情,都是 TipsViewController
的权限。 InteractViewController
不应直接与 TipsViewController
的任何媒体互动。