【问题标题】:Storyboard UIView Objects Not Instantiating故事板 UIView 对象未实例化
【发布时间】:2015-06-07 14:36:24
【问题描述】:

我正在开发一个使用 Swift 和 Storyboards 的项目。它是从传统的 IB 和 Objective-C 项目转换而来的项目。我在加载视图时遇到了 UITableView 实例化的问题。让我解释。

该项目是一个导航项目。这是故事板的概述。

Storyboard 的第一个 viewController 是 HomeViewController,它是一个显示一般信息的登录页面。下一个VC叫做FeedViewController,显示了一些RSS提要。您可以在下图中看到 NavigationController、HomeViewController 和 FeedViewController 的扩展屏幕截图。

我的问题是我无法让 tableView 实例化。我首先检查以确保我的 tableView 已作为插座连接,并且 dataSource 和委托属性已连接。您可以在下面的图片中看到这一点。

在我的 FeedViewController 类中,我有一个名为 feedsTableView 的 Outler 属性。您可以在下面的代码中看到声明。

    class FeedViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, FLODataHandlerDelegate
{
    // View Contoller and Protocol Properties
    var floView : FLOViewController?
    var dataHandler : FLODataHandler?

    // Interface and Content Properties
    var refreshControl : UIRefreshControl?

    // IBOutlets
    @IBOutlet weak var feedsTableView: UITableView!
    @IBOutlet weak var backgroundImage: UIImageView!

在 HomeViewController 中,我有一个 FeedViewController 属性,我打算使用它来访问 FeedViewController 的 feedsTableView。

    class HomeViewController: UIViewController, FLODataHandlerDelegate, MFMailComposeViewControllerDelegate
{
    // View Contoller and Protocol Properties
    var feedViewController : FeedViewController?
    var dataHandler : FLODataHandler?

当 HomeViewController 的 viewDidLoad() 方法被调用时,我启动 dataHandler - 它实例化 FeedViewController - 并将其设置为我的 FeedViewController 属性。

override func viewDidLoad()
{
    super.viewDidLoad()

    // Set up the gesture recognizer to allow for swiping to the feed VC.
    let recognizer = UISwipeGestureRecognizer(target: self, action: Selector("goToNext"))
    recognizer.direction = UISwipeGestureRecognizerDirection.Left
    self.view.addGestureRecognizer(recognizer)

    // Start the data handler
    self.setUpDataHandler()
}

setUpDataHandler()

func setUpDataHandler()
    {
        // Intitalize FeedVC for use later in the VC
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("FeedViewController") as! FeedViewController
        self.feedViewController = vc
    }

我还有一个故障保险,如果有人在调用 setUpDataHandler() 方法之前访问 FeedViewController,那么我也会在这里实例化 FeedViewController。

func goToNext()
{
    // Grab the feedViewController so it can be pushed onto the stack.  Make sure you set up the storyboard identifier.
    let feedVC = self.storyboard!.instantiateViewControllerWithIdentifier("FeedViewController") as! FeedViewController
    self.feedViewController = feedVC
    self.navigationController!.pushViewController(self.feedViewController!, animated: true)
}

但是 feedsTableView 没有被实例化。在 FeedViewController 的 viewDidLoad() 方法中,我尝试将 feedsTableView 添加到 UIRefreshController。

override func viewDidLoad()
{
    super.viewDidLoad()

    self.refreshControl = UIRefreshControl()
    self.refreshControl!.addTarget(self, action: "refreshInvoked:state:", forControlEvents: UIControlEvents.ValueChanged)
    // See the note in viewDidLoad in FLOViewController.
    self.feedsTableView.addSubview(self.refreshControl!)
}

应用程序运行时出现以下错误。

致命错误:在展开可选值时意外发现 nil

下图显示的是这个被调用的。它是 FeedViewController 的 viewDidLoad()。正如您在图片中看到的那样,我什至尝试在将 feedsTableView 添加到 UIRefreshController 之前对其进行实例化,但仍然出现错误。

任何帮助将不胜感激。

保重,

乔恩

【问题讨论】:

    标签: swift storyboard instantiation


    【解决方案1】:

    它在最后一种情况下不起作用的原因是,在您手动实例化 UITableView 并将其分配给 self.feedsTableView 的情况下,self.feedsTableView 被声明为 weak。因此,表格视图开始存在,被分配,然后因为没有内存管理而消失得无影无踪。当您到达最后一行时,self.feedsTableView 再次变为 nil

    因此,最后一种情况的解决方案是从您的 feedsTableView 声明中删除 weak 名称。

    在最后一种情况下,这将使您摆脱崩溃。但是你当然不会看到任何东西,因为你没有同时将表格视图插入到你的界面中。

    【讨论】:

    • 不过,我无法解释基本情况,因为我不理解情节提要中的视图控制器结构:对我的血液来说太奇怪了。
    • 很遗憾,这不起作用。我删除了弱声明,但它并没有纠正问题。感谢您的意见。
    • 它不会解决它。我只是在谈论您手动实例化的最后一次绝望尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2012-06-08
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多