Swift 3 更新中的错误 - 在展开可选值时意外发现 nil
Posted
技术标签:
【中文标题】Swift 3 更新中的错误 - 在展开可选值时意外发现 nil【英文标题】:Error in Swift 3 update - Unexpectedly found nil while unwrapping an optional value 【发布时间】:2016-10-13 23:26:54 【问题描述】:我正在尝试将图像从“tableview 控制器”分离到可以“全屏”查看图像的单独视图中。在我更新到 Swift 3 之前,我使用的代码运行良好。我一直在阅读有关展开可选值的内容,但我无法弄清楚这里的错误是什么。
谢谢!
错误所在的代码行:
Detailimageview.sd_setImage(with: URL(string:self.sentData1))
错误:致命错误:在展开可选值时意外发现 nil
发生此错误的“全屏”视图控制器:
import UIKit
class PhotoView: UIViewController, UIPopoverPresentationControllerDelegate, UIScrollViewDelegate
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var Detailimageview: UIImageView!
var sentData1:String!
func scrollViewDidZoom(_ scrollView: UIScrollView)
let imageViewSize = Detailimageview.frame.size
let scrollViewSize = scrollView.bounds.size
let verticalPadding = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
let horizontalPadding = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0
scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
return Detailimageview
func setZoomScale()
let imageViewSize = Detailimageview.bounds.size
let scrollViewSize = scrollView.bounds.size
let widthScale = scrollViewSize.width / imageViewSize.width
let heightScale = scrollViewSize.height / imageViewSize.height
scrollView.minimumZoomScale = min(widthScale, heightScale)
scrollView.zoomScale = 1.0
override func viewWillLayoutSubviews()
setZoomScale()
override func viewDidLoad()
super.viewDidLoad()
Detailimageview.sd_setImage(with: URL(string:self.sentData1))
// Do any additional setup after loading the view.
setZoomScale()
func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
func viewForZooming(in scrollView: UIScrollView) -> UIView?
return containerView
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
@IBAction func DismissView(_ sender: AnyObject)
self.dismiss(animated: true, completion: nil)
@IBAction func showPopup(_ sender: AnyObject)
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParentViewController: self)
override var prefersStatusBarHidden: Bool
get
return true
“tableview 控制器”:
import UIKit
class ListViewController: UITableViewController
var imageURLs = [String]()
let cellVenue = ["Example Venue","Example Venue1","Example Venue2","Example Venue3","Example Venue4","Example Venue5"]
let cellLocation = ["Example Venue, Location","Example Venue, Location1","Example Venue, Location2","Example Venue, Location3","Example Venue, Location4","Example Venue, Location5"]
let cellDate = ["Example Date, 1970","Example Date, 1971","Example Date, 1972","Example Date, 1973","Example Date, 1974","January 1st, 1975"]
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
override func viewDidLoad()
super.viewDidLoad()
imageURLs = ["https://i.imgur.com/bSfVe7l.jpg","https://i.imgur.com/vRhhNFj.jpg","https://i.imgur.com/bSfVe7l.jpg","https://i.imgur.com/vRhhNFj.jpg","https://i.imgur.com/bSfVe7l.jpg"]
self.tableView.separatorStyle = .none
// tableView.indicatorStyle = UIScrollViewIndicatorStyle.white
self.view.backgroundColor = UIColor.black
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
navigationController!.navigationBar.barTintColor = UIColor.black
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return imageURLs.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell: ListViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ListViewCell
let imageView = cell.viewWithTag(1) as! UIImageView
imageView.sd_setImage(with: URL(string: imageURLs[indexPath.row]))
imageView.sd_setHighlightedImage(with: URL(string: imageURLs[indexPath.row]), options: [.continueInBackground, .progressiveDownload, .avoidAutoSetImage])
cell.cellVenue.text = cellVenue[indexPath.row]
cell.cellLocation.text = cellLocation[indexPath.row]
cell.cellDate.text = cellDate[indexPath.row]
return cell
func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
if (segue.identifier == "DetailView")
// segue.destination is correct, xcode keeps switching it to segue.description
let VC = segue.destination as! PhotoView
if let indexpath = self.tableView.indexPathForSelectedRow
let Imageview = imageURLs[indexpath.row] as String
VC.sentData1 = Imageview
override var prefersStatusBarHidden: Bool
get
return true
【问题讨论】:
【参考方案1】:看起来这是一个视图生命周期问题。子控制器上的 viewDidLoad
在调用 prepareForSegue
之前或至少在父控制器上完成之前被调用。环顾四周,我看到关于这是否应该发生的相互矛盾的信息,而且我通常不使用故事板,所以我自己并不积极。在任何情况下,一个简单的解决方法就是将您的图像设置代码移出viewDidLoad
并移入viewWillAppear
。该 URL 肯定应该在此时设置,并且您的可选项将被成功解包。
【讨论】:
感谢您的信息。将其移至:override func viewWillAppear(_ animated: Bool) Detailimageview.sd_setImage(with: URL(string:self.sentData1)) 位于 viewDidLoad 之后。仍然出现同样的错误。 这里还有其他事情发生,因为问题不在您发布的代码中。你有没有在错误发生前设置断点来查看sentData1
的实际值是多少?
我没有。我不太确定如何读取该值。我检查了我的网点,它们已经连接起来了
这是一篇很好的关于使用 Xcode/Swift 进行基本调试的文章:natashatherobot.com/swift-debugging以上是关于Swift 3 更新中的错误 - 在展开可选值时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中的非英文字符给出:致命错误:在展开可选值时意外发现 nil