故事板UIView对象未实例化

时间:2015-06-07 14:36:25

标签: swift storyboard instantiation

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

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

enter image description here

故事板的第一个viewController是HomeViewController,是一个显示常规信息的登陆页面。下一个VC被称为FeedViewController,显示了许多RSS提要。您可以在下图中看到NavigationController,HomeViewController和FeedViewController的扩展屏幕截图。

enter image description here

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

enter image description here

在我的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的feedTableView。

    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)
}

然而,feedTableView没有被实例化。在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()。正如你在图片中看到的那样,我甚至尝试在将FeedTableView添加到UIRefreshController之前实例化它,我仍然得到错误。

enter image description here

非常感谢任何帮助。

小心,

乔恩

1 个答案:

答案 0 :(得分:0)

在手动实例化UITableView并将其分配给self.feedsTableView的最后一种情况下,它无法工作的原因是self.feedsTableView被声明为weak。因此,表视图存在,被分配,并且在一阵烟雾中消失,因为它没有内存管理。当您到达最后一行时,self.feedsTableView再次为nil

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

这会让你在最后一个案例中超越崩溃。但是当然你不会看到任何东西,因为你还没有将表视图插入你的界面。