2016-07-16 5 views
2

나는 OrderTable 유형의 레코드를 저장하고 테이블에서 저장된 레코드를 가져 와서 테이블을 다시로드한다는 점에서 신속한 CoreData의 테이블을 보유하고 있습니다. 클로저의 도움으로 그 배열 값을 모든 레코드를 저장하고 루프의 값을 인쇄하는 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

관련 문제