使用委托:在展开可选值时意外发现 nil
Posted
技术标签:
【中文标题】使用委托:在展开可选值时意外发现 nil【英文标题】:Using delegates: unexpectedly found nil while unwrapping an Optional value 【发布时间】:2015-05-30 16:02:54 【问题描述】:我有两个ViewController
s,假设一个名为MainVC
,另一个名为GetCameraRollImageViewController
。在第二个中,有一个UIScrollView
包含一个UIImageView
,因为我使用segue 来显示第二个视图控制器,所以我必须在MainVC
中使用它的委托:
class ViewController: UIViewController, GetTextDelegate, GetCameraRollImageDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate
//
//other codes
//
@IBAction func setNewImageFromCameraRoll(segue:UIStoryboardSegue)
if let newImageVC = segue.sourceViewController as? GetCameraRollImageViewController
var scale:CGFloat = 1.0/newImageVC.scrollView.zoomScale;
var visibleRect:CGRect!
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
visibleRect.origin.y = newImageVC.scrollView.contentOffset.y * scale;
visibleRect.size.width = newImageVC.scrollView.bounds.size.width * scale;
visibleRect.size.height = newImageVC.scrollView.bounds.size.height * scale;
var cr:CGImageRef = CGImageCreateWithImageInRect(newImageVC.inputImage.image?.CGImage,visibleRect)
var cropped:UIImage = UIImage(CGImage: cr)!
imageView.image = cropped
GetCameraRollImageViewController
代码:
import UIKit
protocol GetCameraRollImageDelegate
//
class GetCameraRollImageViewController: UIViewController, UIScrollViewDelegate
var delegate:GetCameraRollImageDelegate? = nil
var inputImageDelegate:UIImage!
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
override func viewDidLoad()
super.viewDidLoad()
self.scrollView.minimumZoomScale = 0.5
self.scrollView.maximumZoomScale = 6.0
self.scrollView.contentSize = self.inputImage.frame.size;
self.scrollView.delegate = self
inputImage.image = inputImageDelegate
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
return self.inputImage
但是当我触发 setNewImageFromCameraRoll()
时,应用程序会因以下错误而崩溃:
fatal error: unexpectedly found nil while unwrapping an Optional value
注意:scrollView
和 inputImage
是有界的,当它们为空时,我不会在 viewDidLoad()
中读取它们。
【问题讨论】:
fatal error: unexpectedly found nil while unwrapping an Optional value in Swift的可能重复 @GoZoner 它没有重复,因为 1)我没有在ViewDidLoad()
中阅读 2)我正在使用 if ..let
【参考方案1】:
我不是 100%,但我相信您的问题是 scrollView 尚未创建。尝试将图像传递给新的视图控制器并在 GetCameraRollImageViewController 的 viewDidLoad 中调整大小。
【讨论】:
【参考方案2】:你的代码有很多问题。
首先,为什么会有一个以segue为参数的IBAction?
通常你所做的就是通过任何方法调用一个 segue,然后实现 preformSegue 方法。每当在视图控制器中触发 segue 时,就会调用该方法。
在 performSegue 中,您可以获得指向目标视图控制器的指针并将参数传递给它。
我不清楚你的 setNewImageFromCameraRoll 方法是如何被调用的,或者它是如何获得一个 segue 对象的。您使用 segue 中的 source 视图控制器对我来说也没有意义。我怀疑该方法没有按您的预期工作。
下一个问题与您尝试对从 segue 获得的视图控制器执行的操作有关。您正在尝试直接操纵它的视图。不要那样做。您应该将视图控制器的视图视为私有视图。相反,您应该向视图控制器添加属性以公开您需要的信息,并引用这些属性。
弄乱另一个视图控制器的视图违反了封装原则。它也经常失败,因为其他视图控制器的视图在它显示在屏幕上之前不会被创建。
【讨论】:
感谢您的回复。这是您的第一个问题answer。对于第二个问题,我不直接操作该视图,我只是在读取一些值。 哦,放松的转场!好的,这就解释了。我没怎么用过。 读取值和写入值一样糟糕,而且很可能会失败。您应该将另一个视图控制器的视图视为私有视图,并添加属性以将信息公开到 VC 的公共接口。【参考方案3】:据我所知,您尚未在 MainVC 中将 V2 类的委托连接到自身 "newImageVC?.delegate=self"
【讨论】:
【参考方案4】:[根据cmets更新]
线
var visibleRect:CGRect!
将visibleRect
分配给nil
,因此是
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
然后将取消引用visibleRect
,找到nil
并产生异常。您需要分配一个CGRect
并将其分配给visibleRect
。
[原答案]
visibleRect
绑定了吗?看起来不像。如果这是绑定的,那么您会注意到 !
的其他用途...您需要绑定您的插座(通常在 InterfaceBuilder 中):
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
也许scrollView
没有绑定,因此,因为它被隐式解包(!
运算符),当您将其引用为nil
时,您的程序将是致命的。
用途:
var visibleRect =
CGRectMake (newImageVC.scrollView.contentOffset.x * scale,
newImageVC.scrollView.contentOffset.y * scale,
newImageVC.scrollView.bounds.size.width * scale,
newImageVC.scrollView.bounds.size.height * scale)
【讨论】:
它在 IB 中是有界的。 这是一个局部变量var visibleRect = CGRectMake(...)
。当你写 var visibleRect:CGRect!
时,visibleRect
就是 nil
并且 将 失败。在您的代码中,您只声明了它的类型,但没有为它分配任何内存。
而且你最好在给它赋值之前先分配它。
谢谢,这就是问题所在!以上是关于使用委托:在展开可选值时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:在展开可选值时意外发现 nil - 当 UITextField 被点击时