2016-07-16 71 views
2

我在swift CoreData中有一個表,我保存OrderTable類型的記錄並從該表中獲取保存的記錄以重新加載表。在閉包的幫助下,我將該數組賦值給OrderTable類型的數組,該數組存儲循環中的所有記錄和打印值,但是當我從該數組中重新加載單元格時,在訪問該對象的鍵時輸出nil值。Coredata managedObject問題swift

請幫助我,我嘗試了一切。這裏是我的代碼並附上問題的截圖。

http://i.stack.imgur.com/sXbrZ.png

##OrderTable.swift database model file 
    ## Save records in database 
      class OrderTable: NSManagedObject { 
      // Insert code here to add functionality to your managed object subclass 

     class func createInManagedObjectContext(moc: NSManagedObjectContext, dict:[String:AnyObject]) -> OrderTable { 
      let newItem = NSEntityDescription.insertNewObjectForEntityForName("OrderTable", inManagedObjectContext: moc) as? OrderTable 

      newItem?.closedDate = dict["closedDate"]as? String; 
      newItem?.modifiedDate = dict["modifiedDate"]as? String 
      newItem?.openedDate = dict["openedDate"]as? String 
      newItem!.items = dict["items"]as? NSData 
      newItem?.server = (dict["server"]as? String?)! 
      newItem?.orderNo = dict["orderNo"]as? String 
      newItem?.totalPrice = dict["totalPrice"]as? String 
      newItem?.tableName = dict["tableName"]as? String 
      moc.saveRecursively() 
      return newItem! 
     } 


    ## Get records from database 

     class func getOrders(moc:NSManagedObjectContext,postCompleted : (succeeded: Bool, result:[OrderTable]?) ->()){ 
      // 9911882342 dilip 

      // var arrayRecords = [OrderTable]() 

      let fetchRequest = NSFetchRequest(); 

      moc.performBlockAndWait({ 
       let entityDescription = NSEntityDescription.entityForName("OrderTable",inManagedObjectContext: moc) 

       fetchRequest.entity = entityDescription 

       do { 
        let resultOrders = try moc.executeFetchRequest(fetchRequest)as? [OrderTable] 

        postCompleted(succeeded:true,result: resultOrders); 

       } catch { 
        let fetchError = error as NSError 
        debugPrint(fetchError) 
        postCompleted(succeeded: false, result: nil) 
       } 


      }) 


     } 
    } 

    ##Controller class to get and load table from database values 


    // 
    // OrderOpenAndCloseViewController.swift 
    // POSApp 
    // 


    import Foundation 
    import UIKit 
    import CoreData 
    class OrderOpenAndCloseViewController: UIViewController{ 

     @IBOutlet weak var tableViewOrderListing: UITableView! 

     var arrayExistingOrders = [OrderTable]() // stores existing orders 

     let coreDataStack = CoreDataStack() // use for multithreaded coredata 

     let viewControllerUtils = ViewControllerUtils();// use for activity indicator 

     //MARK: view Life cycle 

     override func viewDidLoad() { 
      super.viewDidLoad() 
     } 
     override func viewWillAppear(animated: Bool) { 
      super.viewWillAppear(animated) 

     } 
     override func viewDidAppear(animated: Bool) { 
      super.viewDidAppear(animated); 

     // call method to get records from database 
      getOpenExistingOrders(); 
     } 

     //MARK: get all open existing orders from database 

     func getOpenExistingOrders(){ 

      viewControllerUtils.showActivityIndicator(self.view) 

      if let newPrivateQueueContext = 
       self.coreDataStack.newPrivateQueueContext(){ // create new NSmanagedObject context 


       // call getOrder method of OrderTable to get orders from database with the help of closure and assign that to arrayExistingOrders of type OrderTable 

       OrderTable.getOrders(newPrivateQueueContext, postCompleted: { (succeeded, result) in 

        self.arrayExistingOrders = result! 

        let item = self.arrayExistingOrders.last // for value check get last object and print orderNo from that 

        print("order no =%@",item?.orderNo)// prints here value or in loop also 1000-001 etc 

        self.tableViewOrderListing.reloadData() 

        self.viewControllerUtils.hideActivityIndicator(self.view) // hide loader 
       }) 

      } 
     } 
     } 
     //MARK: tableview datasource methods 
    extension OrderOpenAndCloseViewController: UITableViewDataSource, UITableViewDelegate{ 
     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

      return arrayExistingOrders.count // return number of orders 
     } 

     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

      let cell = tableView.dequeueReusableCellWithIdentifier("OrderOpenAndCloseCell", forIndexPath: indexPath)as? OrderOpenAndCloseCell 

      let item = arrayExistingOrders[indexPath.item] 
      print("orderNo =%@",item.orderNo) //here prints orderNo =%@ nil instead of value order no =%@ Optional("1000-001") etc 


      let orderNo = item.orderNo 

      var totalOrderCost:String? 

      if let totalcost = item.totalPrice{ 
       totalOrderCost = totalcost 

      }else{ 
       totalOrderCost = "" 
      } 

      let serverName = item.server 

      let openedDate = item.openedDate 

      cell?.labelOrderNo.text = orderNo; 

      cell?.labelServerName.text = serverName; 

      cell?.labelOpenedDate.text = openedDate 

      cell?.labelTotalPrice.text = totalOrderCost 

      return cell!; 
     } 
     } 

回答

1

您的問題是在這條線:

if let newPrivateQueueContext = 
    self.coreDataStack.newPrivateQueueContext 

您再使用newPrivateQueueContext執行讀取。然後你讓newPrivateContext超出範圍,導致它被釋放。

當您獲取託管對象時,該託管對象需要其託管對象上下文,但它不保留對其的強烈引用。如果託管對象上下文已取消分配,則從其中獲取的任何託管對象現在都無用。您可以打印結果而上下文仍然存在但是隻要您讓它被釋放,就不能再使用結果。

只要您需要使用提取結果,您需要對用於提取的上下文保持強有力的參考。這可能意味着使它成爲視圖控制器的屬性,但有很多方法可以做到這一點。

+0

謝謝湯姆,它幫助我解決這個問題。 – kaushal