2015-06-22 5 views
0

В приложении Swift я представляю представление добавления для добавления элемента в базу данных CoreData. Если я вызову tableview.reloadData(), приложение выйдет из строя на кнопке + на главном экране. Если я опускаю данные перезагрузки, тогда отображается представление добавления и данные добавляются в файл CoreData.tableView.reloadData(), вызывающий сбой приложения

основной вид из configureCell вниз:

func configureCell(cell: TransectTableViewCell, indexPath:NSIndexPath) { 

    let transectEntry = fetchedResultController.objectAtIndexPath(indexPath) as! Transects 

    cell.transectNameLabel.text = transectEntry.transectName 
    cell.transectNameLabel.textColor = UIColor.blackColor() 
    cell.transectNameLabel.shadowColor = UIColor.whiteColor() 
    cell.transectNameLabel.shadowOffset = CGSizeMake(1, 1) 
} 

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
    if editingStyle == .Delete { 
     let countEntry = fetchedResultController.objectAtIndexPath(indexPath) as! Transects 
     coreDataStack.context.deleteObject(countEntry) 
     coreDataStack.saveContext() 
    } 
} 

func tableView(tableView: UITableView, 
    heightForRowAtIndexPath indexPath: NSIndexPath) 
    -> CGFloat { 
     return 50; 
} 

func didFinishViewController(viewController: AddTransectViewController, didSave: Bool) { 

    if didSave { 
     var error: NSError? = nil 
     let context = viewController.context 
     self.coreDataStack.saveContext() 
    } 

    dismissViewControllerAnimated(true, completion: {}) 
} 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

    if segue.identifier == "addTransectSegue" { 

     let newTransectViewController = segue.destinationViewController as! AddTransectViewController 
     let transectEntryEntity = NSEntityDescription.entityForName("Transects", inManagedObjectContext: coreDataStack.context) 
     let newTransectEntry = Transects(entity: transectEntryEntity!, insertIntoManagedObjectContext: coreDataStack.context) 

     newTransectViewController.transectNewEntry = newTransectEntry 
     newTransectViewController.context = newTransectEntry.managedObjectContext 
     newTransectViewController.delegate = self 
    } 

    if segue.identifier == "transectTasksSegue" { 

     let indexPath = tableView.indexPathForSelectedRow()! 
     let transectSelected = fetchedResultController.objectAtIndexPath(indexPath) as! Transects 

     let tasksViewController = segue.destinationViewController as! TransectTasksViewController 
     tasksViewController.coreDataStack = coreDataStack 

     tasksViewController.selectedTransect = transectSelected 

    } 
} 


func controllerDidChangeContent(controller: 
    NSFetchedResultsController) { 
     tableView.reloadData() 
} 

Вид добавления:

import UIKit 
import CoreData 
import Foundation 

protocol TransectDelegate { 

    func didFinishViewController(ViewController:AddTransectViewController, didSave:Bool) 
} 

class AddTransectViewController: UIViewController, UITextFieldDelegate { 

    @IBOutlet weak var transectNameTextField: UITextField! 
    @IBOutlet weak var latitudeTextField: UITextField! 
    @IBOutlet weak var longitudeTextField: UITextField! 
    @IBOutlet weak var altitudeTextField: UITextField! 

    var transectNewEntry: Transects! 

    var context: NSManagedObjectContext! 
    var delegate:TransectDelegate? 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func prefersStatusBarHidden() -> Bool { 
     return true 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    func updateTransectEntry() { 

     if let entry = transectNewEntry { 

      entry.transectName = transectNameTextField.text 
      entry.latitude = latitudeTextField.text 
      entry.longitude = longitudeTextField.text 
      entry.altitude = altitudeTextField.text 
     } 
    } 

    @IBAction func cancelButtonWasTapped(sender: AnyObject) { 
     delegate?.didFinishViewController(self, didSave: false) 
    } 

    @IBAction func saveButtonWasTapped(sender: AnyObject) { 
     updateTransectEntry() 
     delegate?.didFinishViewController(self, didSave: true) 
    } 

} 

Я что-то не хватает, но не может видеть, что. Идеи приветствуются.

приложение зависает на cell.transectNameLabel.text = transectEntry.transectName

с: Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0х0)

Моя настоящая путаница в том, что это работает отлично:

import UIKit 

импорт CoreData

класс PlantSpeciesViewController: UIViewController, NSFetchedResultsControllerDelegate, PlantSpeciesDele ворота, UITableViewDataSource, UITableViewDelegate {

@IBOutlet var tableView:UITableView! 

var coreDataStack: CoreDataStack! 
lazy var fetchedResultController: 
NSFetchedResultsController = self.plantSpeciesFetchedResultsController() 

var plantSpecies: PlantSpecies! 

var selectedFamily: PlantFamily! 

var context: NSManagedObjectContext! 

var plantFamilyName: String! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    tableView.backgroundColor = UIColor.clearColor() 
    view.backgroundColor = UIColor(patternImage: UIImage (named: "Monitor backdrop.png")!) 

    self.title = plantFamilyName 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

func plantSpeciesFetchedResultsController() 
    ->NSFetchedResultsController { 

     fetchedResultController = 
      NSFetchedResultsController(
       fetchRequest: plantSpeciesFetchRequest(), 
       managedObjectContext: coreDataStack.context, 
       sectionNameKeyPath: nil, 
       cacheName: nil) 

     fetchedResultController.delegate = self 

     var error: NSError? = nil 
     if (!fetchedResultController.performFetch(&error)){ 
      println("Error: \(error?.localizedDescription)") 
      abort() 
     } 

     return fetchedResultController 
} 

func plantSpeciesFetchRequest() -> NSFetchRequest { 

    let fetchRequest = NSFetchRequest(entityName: "PlantSpecies") 
    fetchRequest.fetchBatchSize = 20 

    let predicate = NSPredicate(format: "familyName == %@", selectedFamily) 

    fetchRequest.predicate = predicate 

    let sortDescriptor = NSSortDescriptor(key: "plantSpecies", ascending: true) 

    fetchRequest.sortDescriptors = [sortDescriptor] 

    //var error: NSError? 

    return fetchRequest 
} 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 

    return fetchedResultController.sections!.count 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    return fetchedResultController.sections![section].numberOfObjects 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("plantSpeciesCell", forIndexPath: indexPath) as! PlantSpeciesTableViewCell 

    cell.backgroundColor = UIColor.clearColor() 

    configureCell(cell, indexPath: indexPath) 

    return cell 
} 

func configureCell(cell: PlantSpeciesTableViewCell, indexPath:NSIndexPath) { 

    let plantEntry = fetchedResultController.objectAtIndexPath(indexPath) as! PlantSpecies 

    cell.speciesNameLabel.text = plantEntry.plantSpecies 
    cell.speciesNameLabel.textColor = UIColor.blackColor() 
    cell.speciesNameLabel.shadowColor = UIColor.whiteColor() 
    cell.speciesNameLabel.shadowOffset = CGSizeMake(1, 1) 

    cell.speciesImageView.image = UIImage (data: plantEntry.plantImage) 
} 


func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
    if editingStyle == .Delete { 
     let countEntry = fetchedResultController.objectAtIndexPath(indexPath) as! PlantFamily 
     coreDataStack.context.deleteObject(countEntry) 
     coreDataStack.saveContext() 
    } 
} 

func tableView(tableView: UITableView, 
    heightForRowAtIndexPath indexPath: NSIndexPath) 
    -> CGFloat { 
     return 90; 
} 

func didFinishViewController(viewController: AddPlantSpeciesViewController, didSave: Bool) { 

    if didSave { 
     var error: NSError? = nil 
     let context = viewController.context 
     self.coreDataStack.saveContext() 
    } 

    dismissViewControllerAnimated(true, completion: {}) 
} 

// MARK: - Navigation 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

    if segue.identifier == "addSpeciesSegue" { 

     let newPlantViewController = segue.destinationViewController as! AddPlantSpeciesViewController 
     let plantEntryEntity = NSEntityDescription.entityForName("PlantSpecies", inManagedObjectContext: coreDataStack.context) 
     let newSpeciesEntry = PlantSpecies(entity: plantEntryEntity!, insertIntoManagedObjectContext: coreDataStack.context) 

     newPlantViewController.selectedFamily = selectedFamily 

     newPlantViewController.plantNameEntry = newSpeciesEntry 
     newPlantViewController.context = newSpeciesEntry.managedObjectContext 
     newPlantViewController.delegate = self 
    } 
} 

func controllerDidChangeContent(controller: 
    NSFetchedResultsController) { 

     tableView.reloadData() 
} 

}

в сочетании с:

импорта UIKit импорта CoreData Foundation импорт

протокола PlantSpeciesDelegate {

func didFinishViewController(ViewController:AddPlantSpeciesViewController, didSave:Bool) 

}

класс AddPlantSpeciesViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

@IBOutlet weak var plantNameTextField: UITextField! 
@IBOutlet weak var plantImageView: UIImageView! 

@IBOutlet weak var imageSwitch: UISwitch! 

@IBOutlet weak var imageFromFileButton: UIButton! 
@IBOutlet weak var imageFromCameraButton: UIButton! 

let imagePicker = UIImagePickerController() 

var plantNameEntry: PlantSpecies! 
var selectedFamily: PlantFamily! 

var passedPlantFamily: String! 

var newPlantName: String! 
var newImageData: NSData! 

var context: NSManagedObjectContext! 
var delegate:PlantSpeciesDelegate? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    plantImageView.image = UIImage(named: "placeholder image.jpg") 

    imagePicker.delegate = self 

} 

override func prefersStatusBarHidden() -> Bool { 
    return true 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

@IBAction func imageSourceSwitch(sender: AnyObject) { 

    if imageSwitch.on == true 
    { 
     self.imageFromFileButton.enabled = true 
     self.imageFromCameraButton.enabled = false 
    } 

    else 
    { 
     self.imageFromCameraButton.enabled = true 
     self.imageFromFileButton.enabled = false 
    } 
} 


@IBAction func imageFromFile(sender: AnyObject) { 
    imagePicker.sourceType = .PhotoLibrary 
    presentViewController(imagePicker, animated: true, completion: nil) 
} 


@IBAction func imageFromCamera(sender: AnyObject) { 
    imagePicker.sourceType = .Camera 
    presentViewController(imagePicker, animated: true, completion: nil) 
} 

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) { 
    self.plantImageView.image = image 
    dismissViewControllerAnimated(true, completion: nil) 
} 

@IBAction func getPlantName() { 

    newPlantName = plantNameTextField.text 
    plantNameTextField.resignFirstResponder() 
} 

func updateSpeciesEntry() { 

    if let entry = plantNameEntry { 

     entry.plantSpecies = newPlantName 
     entry.plantImage = UIImageJPEGRepresentation(plantImageView.image, 1.0) 
     entry.familyName = selectedFamily 
    } 
} 

@IBAction func cancelButtonWasTapped(sender: AnyObject) { 
    delegate?.didFinishViewController(self, didSave: false) 
} 


@IBAction func saveButtonWasTapped(sender: AnyObject) { 
    updateSpeciesEntry() 
    delegate?.didFinishViewController(self, didSave: true) 
} 

} Итак, в чем разница?

+0

не могли бы вы предоставить сообщение об ошибке? –

+0

Вам нужно больше информации. Какова ошибка сбоя? Где? –

+0

Согласитесь, убедитесь, что ваша точка прерывания ошибок предоставила нам дополнительную информацию. – cjnevin

ответ

1

Причина возникновения сбоя в том, что таблица не может загружать данные, например, значение не существует и не распадается. Поэтому авария происходит, когда вы пытаетесь собрать данные. Проверьте все значения, чтобы убедиться.

2

Это случилось со мной тоже, установил его с:

dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadData() 
} 

, а не только tableView.reloadData() , потому что кажется, что она вызывается из-за неправильной резьбой.

Смежные вопросы