BAD_EXC_ACCESS проверяет наличие данных:SWIFT

У меня есть UITableViewController, что у меня есть данные. Если вы нажмете на строку, вы сможете отредактировать существующие данные, если вы нажмете + в UIBarButtonItem, вы добавите новую информацию. Когда мой Segue передает Core Data Object (vc.managedObjectID), мой контроллер представления "detail" проверяет, есть ли данные в поле firstName или нет.

В Objective-C я бы сделал что-то вроде этого

- (void)refreshInterface
{
    CoreDataHelper *cdh = [CoreDataHelper sharedHelper];
    Cues *existingCues = (Cues*)[cdh.context existingObjectWithID:_cuesNSManagedObjectID error:nil];

    if (!existingCues.cuesName)
    {
        _cueNameTextField.text           = nil;
        self.cueDescriptionTextView.text = nil;
    }
    else
    {
        _cueNameTextField.text           = existingCues.cuesName;
        self.cueDescriptionTextView.text = existingCues.cuesDescription;
    }
}

У меня проблема с проверкой наличия каких-либо данных в firstName: var firstName = playerInformation.firstName вызывает EXC_BAD_ACCESS только при добавлении нового объекта (это означает, что playerInformatin пуст), когда я нажимаю, чтобы просмотреть существующие данные, он возвращает правильный данные. Как проверить, является ли playerInfomation пустым (новая запись) или имеет данные (существующие данные) в Swift?

func refreshInterface(){

    if managedObjectID != nil {
        var playerInformation = managedObjectContext?.existingObjectWithID(managedObjectID!, error: nil) as? PlayerInformation

        var firstName = playerInformation!.firstName //EXC_BAD_ACCESS
        println("firstName \(firstName)")
    }
}

prepareForSegue

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

        if segue.identifier == "addPlayerInformationDetail" {

            println("addPlayerInformationDetail")

            let context = self.fetchedResultsController.managedObjectContext

            let entity  = self.fetchedResultsController.fetchRequest.entity

            let playerInformation = NSEntityDescription.insertNewObjectForEntityForName(entity.name, inManagedObjectContext: managedObjectContext!) as PlayerInformation?

            var vc  = segue.destinationViewController as PlayerInformationDetailTableViewController

            vc.managedObjectID = playerInformation?.objectID

        } else if segue.identifier == "editPlayerInformationDetail" {


            println("editPlayerInformationDetail")

            var indexPath:NSIndexPath = tableView.indexPathForSelectedRow()!

            var vc                    = segue.destinationViewController as PlayerInformationDetailTableViewController

            vc.managedObjectID        = self.fetchedResultsController.objectAtIndexPath(indexPath).objectID

        }

person Paul S.    schedule 02.10.2014    source источник
comment
вызывает EXC_BAD_ACCESS   -  person Paul S.    schedule 02.10.2014


Ответы (2)


Вы можете использовать условное let так:

if let firstName = playerInformation?.firstName {
    println("firstName \(firstName)")
}

Это только развернет необязательное значение, если оно не равно нулю, избегая сбоя.

person Greg    schedule 02.10.2014
comment
if let firstName = playerInformation?.firstName { println("firstName \(firstName)") } Состояние if вызывает ошибку EXC_BAD_ACCESS. - person Paul S.; 02.10.2014
comment
@ПолС. Интересно. Попробуйте if let p = playerInformation { var firstName = p.firstName println("firstName \(firstName)") } - person Greg; 02.10.2014
comment
EXC_BAD_ACCESS в строке var firstname. Это может ничего не стоить, если в представлении переменных (нижняя левая панель отладки) firstName = (String) "" - person Paul S.; 02.10.2014
comment
Каков объявленный тип firstName? Это NSString!? - person Greg; 02.10.2014
comment
PlayerInformation — это NSManagedObject, firstName — это строка. Опять же, когда я запускаю приложение и выбираю ячейку UITableView, в которой есть данные, даже предложенный вами код работает, и первое имя печатается. - person Paul S.; 02.10.2014
comment
Попробуйте написать только if playerInformation != nil, свой исходный код, в операторе if. Если это не сработает, возможно, это ошибка Core Data с необязательными значениями, и нам придется искать обходной путь. - person Greg; 02.10.2014
comment
Я пробовал следующее: var playerInformation = managedObjectContext?.existingObjectWithID(managedObjectID!, error: nil) as? PlayerInformation if playerInformation != nil { var firstName = playerInformation!.firstName //EXC_BAD_ACCESS println("firstName \(firstName)") } та же проблема. - person Paul S.; 02.10.2014
comment
Вы получаете какой-либо вывод журнала ошибок? Отображается ли адрес памяти в виде исключения 0x0 или фактическое значение? - person Greg; 02.10.2014
comment
Не уверен, что это то, о чем вы спрашиваете: EXC_BAD_ACCESS (code =1, address 0x0) на левой панели почти все значения равны 0 - person Paul S.; 02.10.2014
comment
Проблема заключается в том, что необязательное значение firstName установлено равным нулю в Core Data. Изменение типа firstName в объявлении класса на String! может решить эту проблему. Вы также можете попробовать удалить ! из кода в строке, где возникает исключение (если это даже компилируется). Для меня это выглядит как ошибка в компиляторе Swift или Core Data. - person Greg; 02.10.2014

почему-то это работает:

var playerInformation = managedObjectContext?.existingObjectWithID(managedObjectID!, error: nil)
var firstName: AnyObject? = playerInformation?.valueForKey("firstName")
println("firstName \(firstName)")

Если я создам подкласс manageObjectContext как PlayerInformation, я получу EXC_BAD_ACCESS

person Paul S.    schedule 03.10.2014