2015-01-30 6 views
2

동일한 오류가있는 많은 질문이 있지만 해결 방법이없는 것으로 알고 있습니다.fetchedResultsController 핵심 데이터 치명적인 오류 : 예기치 않게 찾지 못했습니다. 옵션 값

CoreData에서 데이터를 저장하고 가져 오는 블로그 리더 앱을 만들고 싶습니다. 나는 CoreData로 JSON 결과를 저장 할 수 있어요,하지만 난이있는 tableView에 표시를 검색하려고 할 때, 그것은 라인에 fatal error: unexpectedly found nil while unwrapping an Optional value와 충돌

다음

let entity = NSEntityDescription.entityForName("Blog", inManagedObjectContext:self.managedObjectContext!)

내 코드입니다 :

import UIKit 
import CoreData 

var activeItem:String = "" 

class CenterViewController: UIViewController, 
    UIWebViewDelegate, NSFetchedResultsControllerDelegate,  
SidePanelViewControllerDelegate { 
var detailViewController: DetailViewController? = nil 
var managedObjectContext: NSManagedObjectContext? = nil 

@IBOutlet weak var titleLabel: UILabel! 
@IBOutlet weak var tableview: UITableView! 
@IBOutlet weak var webview2: UIWebView! 


var delegate: CenterViewControllerDelegate? 

// MARK: Button actions 

@IBAction func kittiesTapped(sender: AnyObject) { 
delegate?.toggleLeftPanel?() 
} 

@IBAction func puppiesTapped(sender: AnyObject) { 
delegate?.toggleRightPanel?() 
} 

    func animalSelected(animal: Animal) { 

var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
var context: NSManagedObjectContext = appDel.managedObjectContext! 
var newBlogItem:NSManagedObject 
let session = NSURLSession.sharedSession() 
var error : NSError? 

let task = session.dataTaskWithURL(animal.url!, completionHandler: {data, response, error -> Void in 

    if (error != nil){ 
     println(error) 

    }else{ 


     let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary 
     var posts = [[String:String]()] 

     var post:AnyObject 

     var authorDictionary:AnyObject 
     var newBlogItem:NSManagedObject 
     for var i = 0; i < jsonResult["posts"]!.count; i++ 

     { 
     posts.append([String:String]()) 
     post = jsonResult["posts"]![i] as NSDictionary 
     posts[i]["title"] = post["title"] as? NSString 
     posts[i]["publishedDate"] = post["date"] as? NSString 
     posts[i]["content"] = post["content"] as? NSString 
     authorDictionary = post["author"] as NSDictionary 
     posts[i]["author"] = post["name"] as? NSString 



      newBlogItem = NSEntityDescription.insertNewObjectForEntityForName("Blog", inManagedObjectContext: context) as NSManagedObject 
      newBlogItem.setValue(posts[i]["title"], forKey: "title") 
      newBlogItem.setValue(posts[i]["publishedDate"], forKey: "publishedDate") 
      newBlogItem.setValue(posts[i]["content"], forKey: "content") 
      newBlogItem.setValue(posts[i]["author"], forKey: "author") 

      context.save(nil) 

     } 
     var request = NSFetchRequest(entityName: "Blog") 
     request.returnsObjectsAsFaults = false 
     var results = context.executeFetchRequest(request, error: nil) 
     println(results) 

    } 

}) 

task.resume() 
    delegate?.collapseSidePanels?() 
} 

// MARK: - Table View 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 


    return self.fetchedResultsController.sections!.count 
    // return 1 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo 
    return sectionInfo.numberOfObjects 
    //return 20 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 
    // self.configureCell(cell, atIndexPath: indexPath) 
    cell.textLabel?.text = "blog item" 
    return cell 
} 

func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { 
    // Return false if you do not want the specified item to be editable. 
    return true 
} 

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
    if editingStyle == .Delete { 
     let context = self.fetchedResultsController.managedObjectContext 
     context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject) 

     var error: NSError? = nil 
     if !context.save(&error) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      //println("Unresolved error \(error), \(error.userInfo)") 
      abort() 
     } 
    } 
} 

func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) { 
    let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject 
    cell.textLabel?.text = object.valueForKey("title")!.description 
} 



// MARK: - Fetched results controller 

var fetchedResultsController: NSFetchedResultsController { 
    if _fetchedResultsController != nil { 
     return _fetchedResultsController! 
     } 

     let fetchRequest = NSFetchRequest() 
     // Edit the entity name as appropriate. 
    let entity = NSEntityDescription.entityForName("Blog", inManagedObjectContext:self.managedObjectContext!) 
     fetchRequest.entity = entity? 

     // Set the batch size to a suitable number. 
     fetchRequest.fetchBatchSize = 20 

     // Edit the sort key as appropriate. 
     let sortDescriptor = NSSortDescriptor(key: "publishedDate", ascending: false) 
     let sortDescriptors = [sortDescriptor] 

     fetchRequest.sortDescriptors = [sortDescriptor] 

     // Edit the section name key path and cache name if appropriate. 
     // nil for section name key path means "no sections". 
     let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Slide Out Tutorial") 
     aFetchedResultsController.delegate = self 
     _fetchedResultsController = aFetchedResultsController 

     var error: NSError? = nil 
     if !_fetchedResultsController!.performFetch(&error) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      //println("Unresolved error \(error), \(error.userInfo)") 
      abort() 
     } 

     return _fetchedResultsController! 
} 
var _fetchedResultsController: NSFetchedResultsController? = nil 

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    self.tableview.beginUpdates() 
} 

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 
    switch type { 
    case .Insert: 
     self.tableview.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    case .Delete: 
     self.tableview.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    default: 
     return 
    } 
} 

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath) { 
    switch type { 
    case .Insert: 
     tableview.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
    case .Delete: 
     tableview.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
    case .Update: 
     self.configureCell(tableview.cellForRowAtIndexPath(indexPath)!, atIndexPath: indexPath) 
    case .Move: 
     tableview.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     tableview.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
    default: 
     return 
    } 
} 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    self.tableview.endUpdates() 
} 

} I 1 돌아가서 numberOfSectionsInTableView에서 각각 func tableView(tableView: UITableView, numberOfRowsInSection section: Int)에서 20 돌아올 때

가있는 tableview 20 회 텍스트 "블로그 항목"을 표시하고, 데이터가 표시된다 양론 올레. 그러나 내가 매뉴얼 리턴 값을 주석 처리하고, 원래 값을 사용하기를 원할 때, 앱은 위에서 언급 한 라인에서 충돌합니다.

나는 fetchedResultsController과 관련이 있다면 추측하고 있습니다.

Pls 도움. 어제부터 이것에 머물렀다

+0

당신은 설정해야 self.managedObjectContext의 값은 nil로 초기화되고 설정되지 않습니다. – pbasdf

+0

@pbasdf 당신이 할 수있는 방법을 알려주는 pls. 신속하고 새로운 개별 프로젝트를 혼합하여 여기에 도달 할 수있다. –

답변

5

self.managedObjectContext (현재는 0이며 오류의 원인이 됨)을 설정해야합니다. 당신은 viewDidLoad 이르면 뷰 컨트롤러의 인생에서 호출 된 함수 중 하나에 설정할 수 있지만, 다른 방법이처럼 fetchedResultsController를 초기화하는 때를 설정하는 것입니다 :

var fetchedResultsController: NSFetchedResultsController { 
    if _fetchedResultsController != nil { 
     return _fetchedResultsController! 
    } 
    var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
    self.managedObjectContext = appDel.managedObjectContext 

    let fetchRequest = NSFetchRequest() 
    // Edit the entity name as appropriate. 
    let entity = NSEntityDescription.entityForName("Blog", inManagedObjectContext:self.managedObjectContext!) 
    fetchRequest.entity = entity? 
    ... 
+0

고마워 톤 .. 완벽한 작품 :) –

+0

또한 발견 내 컨텍스트를 인스턴스화하는 걸 깜빡 했어, 내가 보지 않고 있었던 1 개의 장소, 감사!! – kpierce8

+0

@pbasdf 오 이런! 방금 내 목숨을 구했어! 감사. 나는 8 시간 동안 디버거에서 단계별로 진행하는 동안 내 주위에 내 머리를 잡으려고 노력했습니다 ... 감사합니다! –