Swift 对象未传入NavigationController

Swift 对象未传入NavigationController,swift,uinavigationcontroller,Swift,Uinavigationcontroller,我遇到了一个让我很困惑的问题。我正在将一个项目从Objective-C转换为Swift,并且第一次使用故事板。该应用程序下载RSS数据,并将标题、链接和发布日期存储在CoreData的文章对象中。当用户单击一行时,它将在webView中加载文章 我现在的问题是将Article对象传递给webView。我可以通过放置在tableViewCell上的按钮来传递它,但选择该单元格会导致应用程序崩溃,并且它表示传递给webView的文章对象为零。但是,如果我在用println()传递它之前测试它,它会显

我遇到了一个让我很困惑的问题。我正在将一个项目从Objective-C转换为Swift,并且第一次使用故事板。该应用程序下载RSS数据,并将标题、链接和发布日期存储在CoreData的文章对象中。当用户单击一行时,它将在webView中加载文章

我现在的问题是将Article对象传递给webView。我可以通过放置在tableViewCell上的按钮来传递它,但选择该单元格会导致应用程序崩溃,并且它表示传递给webView的文章对象为零。但是,如果我在用println()传递它之前测试它,它会显示它不是nil

这是我用于单元格上的按钮的代码

@IBAction func article(sender: AnyObject)
    {
        // Pulling the most recent story to display on the HomeViewController
        let fetchRequest = NSFetchRequest(entityName: "Article")
        let predicate = NSPredicate(format: "feed == 'FLO Cycling' OR feed == 'Triathlete' OR feed == 'Velo News' OR feed == 'Cycling News' OR feed == 'Ironman'")
        fetchRequest.predicate = predicate
        let sortDescriptor = NSSortDescriptor(key: "pubDate", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]
        
        // Set up NSError for the Fetch
        var fetchError : NSError?
        // When you perform a fetch the returned object is an array of the Atricle Entities.
        let fetchedObjects = self.articleContext.executeFetchRequest(fetchRequest, error: &fetchError) as! [Article]
        
        //Grab the latest Article and place the title in the label in the HomeViewController
        self.latestArticle = fetchedObjects.last
        
        // Grab the latestArticleViewController so it can be presented modally.  Make sure you set up the storyboard identifier.
        self.articleView = self.storyboard!.instantiateViewControllerWithIdentifier("ArticleViewController") as? ArticleViewController
        self.articleView!.currentArticle = self.latestArticle
        self.articleView!.articleContext = self.articleContext
        self.presentViewController(self.articleView!, animated: true, completion: nil)
    }
下面是我用于DidSelectRowatineXpath的代码

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    let selectedArticle = self.fetchedResultsController!.objectAtIndexPath(indexPath) as? Article
    self.articleView = self.storyboard!.instantiateViewControllerWithIdentifier("ArticleViewController") as? ArticleViewController
    self.articleView!.currentArticle = selectedArticle
    self.articleView!.articleContext = self.articleContext
    println("This is coming from didSelectRowAtIndexPath \(self.articleView!.currentArticle!.link)")

    self.navigationController!.pushViewController(self.articleView!, animated: true)

    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
这是一张手机上有按钮的应用程序的图片

@IBAction func article(sender: AnyObject)
    {
        // Pulling the most recent story to display on the HomeViewController
        let fetchRequest = NSFetchRequest(entityName: "Article")
        let predicate = NSPredicate(format: "feed == 'FLO Cycling' OR feed == 'Triathlete' OR feed == 'Velo News' OR feed == 'Cycling News' OR feed == 'Ironman'")
        fetchRequest.predicate = predicate
        let sortDescriptor = NSSortDescriptor(key: "pubDate", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]
        
        // Set up NSError for the Fetch
        var fetchError : NSError?
        // When you perform a fetch the returned object is an array of the Atricle Entities.
        let fetchedObjects = self.articleContext.executeFetchRequest(fetchRequest, error: &fetchError) as! [Article]
        
        //Grab the latest Article and place the title in the label in the HomeViewController
        self.latestArticle = fetchedObjects.last
        
        // Grab the latestArticleViewController so it can be presented modally.  Make sure you set up the storyboard identifier.
        self.articleView = self.storyboard!.instantiateViewControllerWithIdentifier("ArticleViewController") as? ArticleViewController
        self.articleView!.currentArticle = self.latestArticle
        self.articleView!.articleContext = self.articleContext
        self.presentViewController(self.articleView!, animated: true, completion: nil)
    }

这就是我点击按钮时发生的情况

这是我触摸电池时从控制台获得的输出。可以看到println()显示文章有一个链接

这是来自DidSelectRowatineXpath 致命错误:在展开可选值时意外发现nil

下面是应用程序崩溃时的屏幕截图

任何帮助都将不胜感激

当前文章声明和初始化

currentArticle在ArticleViewController中以以下方式声明

    class ArticleViewController: UIViewController, UIWebViewDelegate, MFMailComposeViewControllerDelegate
{
    // Properties
    var currentArticle : Article?
}
至于didSelectRowAtIndexPath方法中的初始化,我执行以下操作来初始化我加载的ArticleViewController的值

    let selectedArticle = self.fetchedResultsController!.objectAtIndexPath(indexPath) as? Article
self.articleView!.currentArticle = selectedArticle
这相当于当我用以下按钮点击按钮时所做的操作。或者至少我认为是一样的

self.latestArticle = fetchedObjects.last
self.articleView!.currentArticle = self.latestArticle
抛出两个错误

2015-05-31 18:42:38.227浮选1.1.1[98389:6596654]岩心数据: 错误:调用NSManagedObject类上指定的初始值设定项失败 “FLOCYCLING”文章2015-05-31 18:42:38.227 FLOCycling1.1.1[98389:6596654]-[FLOCycling1_1_1.文章链接]: 已将无法识别的选择器发送到实例0x7f81ead7f940

保重,


Jon

您调用var currentArticle时,它还没有初始化,我在您的pic中看到您已经在代码中进行了一些延迟初始化,请重复此变量,所有操作都应该可以正常开始,我在下面添加了一个示例:

lazy var currentArticle: Article = {
    let article = Article()
    //any other initialization you need
    return article
}()

我希望这对你有帮助

我不明白为什么这样解决了这个问题,但我会解释我做了什么。也许有人有更多的故事板经验可以解释

对于RSS解析器排序的每个提要,我使用了几个ViewController。因为所有文章都以相同的格式显示,所以我使用了一个ArticleViewController来显示文章。下图显示了故事板的整体层次结构。最右边的VC是ArticleViewController,左边的七个是RSS提要的VC

我为每个RSS提要创建了一个segue,以指向ArticleViewController。每个人都有一个唯一的名字,我可以在prepareForSegue中使用。您可以在下面的缩放视图中看到分段

最初,我尝试使用prepareForSegue方法和以下代码将Article对象传递给ArticleViewController

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
       if segue.identifier == "floArticleSegue"
       {
           if let indexPath = self.storyTableView.indexPathForSelectedRow()            {
               let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Article

               (segue.destinationViewController as! ArticleViewController).currentArticle = object
           }
       }
}
当我这样做时,对象没有被传递到文章ViewController。然后我尝试了didSelectRowAtIndexPath方法,同样的问题也出现了。为了清楚起见,我在这里重复了这个错误

这是来自didSelectRowAtIndexPath致命错误:在展开可选值时意外发现nil

为了解决这个问题,我删除了RSS源VC到ArticleViewController的segue,并使用了我以前使用的相同代码。该代码如下所示

let selectedArticle = self.fetchedResultsController!.objectAtIndexPath(indexPath) as? Article
self.articleView = self.storyboard!.instantiateViewControllerWithIdentifier("ArticleViewController") as? ArticleViewController
self.articleView!.currentArticle = selectedArticle
self.articleView!.articleContext = self.articleContext
println("This is coming from didSelectRowAtIndexPath \(self.articleView!.currentArticle!.link)")

self.navigationController!.pushViewController(self.articleView!, animated: true)

tableView.deselectRowAtIndexPath(indexPath, animated: true)
无论出于何种原因,当segue从情节提要中删除时,对象被传递,应用程序可以正常工作。我希望这能帮助其他人,也许有人能解释原因

保重,


Jon

你能告诉我们你是如何声明和初始化currentArticle的吗?我在末尾添加了代码。如果您还想看其他内容,请告诉我。我尝试了一下,并抛出了两个错误。你可以在上面帖子的末尾看到它们。感谢您提供的信息。您的文章类似乎也依赖于要初始化的其他变量。我建议您创建一个新的变量作为字符串,以保存您正在传递的值,并使用该字符串以旧的方式初始化您的文章。让我知道它是否有效