2016-07-16 7 views
2

私はOrderTable型のレコードを保存し、そのテーブルから保存されたレコードをフェッチしてテーブルをリロードするという点で、迅速なCoreDataのテーブルを持っています。 closureの助けを借りて、配列値をすべてのレコードを格納し、ループ内の値を格納するOrderTable型の配列に割り当てますが、その配列からセルをリロードすると、そのオブジェクトのキーにアクセスするときにnil値を出力します。Coredata managedObject issue 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

あなたの問題は、この行である:あなたはその後、フェッチを実行するためにnewPrivateQueueContextを使用

if let newPrivateQueueContext = 
    self.coreDataStack.newPrivateQueueContext 

。次に、newPrivateContextをスコープから外して、割り当てを解除します。

管理対象オブジェクトを取得するとき、その管理対象オブジェクトには管理対象オブジェクトコンテキストが必要ですが、管理対象オブジェクトコンテキストを強く参照する必要はありません。管理対象オブジェクトのコンテキストが割り当て解除された場合、そこからフェッチされた管理対象オブジェクトは無用になります。コンテキストがまだ存在する間に結果を印刷することはできますが、割り当てを解除するとすぐに結果を使用することはできません。

フェッチの結果を使用する必要がある限り、フェッチに使用するコンテキストを強く参照する必要があります。これはおそらくビューコントローラのプロパティにすることを意味しますが、それを行う方法はたくさんあります。

+0

ありがとうTom、それは私がその問題を解決するのを助けます。 – kaushal

関連する問題