API JSON & UIPageViewController 可选 Nil
Posted
技术标签:
【中文标题】API JSON & UIPageViewController 可选 Nil【英文标题】:API JSON & UIPageViewController optional Nil 【发布时间】:2015-04-18 06:18:33 【问题描述】:好的,我正在尝试设计一个浏览量滑块,它使用此tutorial 作为基础从 API 检索图像 url。
我已经编写了图像的异步下载并将其附加到 pageImages 数组。这部分工作正常。
但是,当我尝试在模拟器中运行应用程序时收到错误消息:
致命错误:在展开可选值时意外发现 nil
由于某种原因,获取 JSON 对象并填充 pageImages 数组发生在我调用辅助方法 viewControllerAtIndex 之后。
我的代码
class ViewController: UIViewController, UIPageViewControllerDataSource
var pageViewController: UIPageViewController!
var pageImages = NSArray()
var jsonData = NSArray()
override func viewDidLoad()
super.viewDidLoad()
###THIS EXECUTES AFTER MY HELPER METHOD viewControllerAtIndex
self.fetchPublishers()
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
var startVC = self.viewControllerAtIndex(0) as ContentViewController
var viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 30, self.view.frame.width, self.view.frame.size.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound)
return nil
index--
return self.viewControllerAtIndex(index)
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound)
return nil
index++
if (index == self.pageImages.count)
return nil
return self.viewControllerAtIndex(index)
func viewControllerAtIndex(index: Int) -> ContentViewController
if ((self.pageImages.count == 0) || (index >= self.pageImages.count))
return ContentViewController()
var vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
vc.imageFile = self.pageImages[index] as! String
vc.pageIndex = index
return vc
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
return self.pageImages.count
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
return 0
func fetchPublishers ()
var req:Request = Alamofire.request(OauthToken.Router.ReadPublishers(""))
var aClosure = (req:NSURLRequest, response:NSHTTPURLResponse?, JSON:AnyObject?, error:NSError?) -> Void in
if (error != nil)
println(error)
println("Couldn't connection to server.")
else
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
self.jsonData = JSON as! NSArray!
var baseUrl: String = "http://0.0.0.0:3000"
self.pageImages = JSON!.valueForKey("photo_url") as! NSArray!
###Prints/executes after
println(self.pageImages)
req.responseJSON(aClosure)
ContentViewController
class ContentViewController: UIViewController
@IBOutlet weak var imageView: UIImageView!
var pageIndex: Int!
var imageFile: String!
override func viewDidLoad()
super.viewDidLoad()
####THE ERROR HAPPENS HERE
self.imageView.image = UIImage(named: self.imageFile)
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:事情的发生是不按顺序发生的,因为引用AlamoFire github page:“Alamofire 中的网络是异步完成的。”这意味着aClosure
中的代码在收到来自服务器的响应之前不会执行,但您的viewDidLoad
的执行将继续进行。
结果是,当调用viewControllerAtIndex
设置startVC
时,pageImages数组为空,执行return ContentViewController()
。这将实例化一个空的内容视图控制器,并且由于它没有链接到情节提要,因此出口imageView
为零(实际上imageFile
为零)。这就是您收到错误的原因。
因此,您需要修改 viewControllerAtIndex
中的 if 语句,以便在数组为空时显示更有用的信息 - 可能是一个视图控制器,其中包含向用户显示数据正在下载的消息,以及系统正在下载的视觉指示器工作。
当数据确实从服务器到达时,您必须找到一种方法来重新加载页面视图控制器。为此,您应该在aClosure
的末尾添加一些代码。在本教程中,有一个函数 restartAction
可以执行必要的操作,因此要么调用它,要么将代码复制到闭包中。
最后,因为最后一步涉及 UI 更新,它必须在主队列上运行。因此,您需要修改您的 dispatch_async
调用(在闭包中)以使用主队列,而不是全局队列。有关详细说明,请参阅 this answer。
【讨论】:
以上是关于API JSON & UIPageViewController 可选 Nil的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableView 下方的 UIPageView 上检测滑动事件
如何最好地将使用一个 UIViewController 将所有页面作为 UIView 处理为 StoryBoarding 和 UIPageView 的图书应用程序转换?