Основные данные обнаруживают строку или целое число? - PullRequest
1 голос
/ 12 декабря 2011

Я встроил некоторую поддержку Core Data в свое приложение из примера Core Data Books.В примере используются даты и строки.Однако я попытался добавить возможность добавлять и редактировать целочисленное значение.

//If the value is a string
if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) {
        textField.hidden = NO;
        datePicker.hidden = YES;
        textField.text = [editedObject valueForKey:editedFieldKey];
        textField.placeholder = self.title;
        [textField becomeFirstResponder];
    }
    //If the value is a number
    else {
        textField.hidden = NO;
        datePicker.hidden = YES;
        textField.text = [[editedObject valueForKey:editedFieldKey] stringValue];
        textField.placeholder = self.title;
        [textField becomeFirstResponder];
    }

Первый оператор if - это пример кода (без проверки, если это строка, я добавил это), и я добавилОператор else запускается, когда это не строка, а целое число.Это работает, однако теперь, когда я редактирую строку, она пропускает оператор if, поэтому строка: if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) как-то не работает.

Надеюсь, вы поможете.Дайте мне знать, если вам нужно больше.Если вы посмотрите на пример CoreDataBooks от Apple, мой код такой же, только я добавил поле, которое принимает целое число 16.

РЕДАКТИРОВАТЬ:

При установке точки останова на первом, еслиоператор и возвращая po [editedObject valueForKey:EditedFiledKey] в консоли я получаю: Can't print the description of a NIL object.

Я предполагаю, что это потому, что его до создания объекта?Это происходит, когда появляется представление (представление для ввода новой строки).

При нажатии кнопки сохранения запускается этот код:

- (IBAction)save {

    // Set the action name for the undo operation.
    NSUndoManager * undoManager = [[editedObject managedObjectContext] undoManager];
    [undoManager setActionName:[NSString stringWithFormat:@"%@", editedFieldName]];

    // Pass current value to the edited object, then pop.
    if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) {
        [editedObject setValue:textField.text forKey:editedFieldKey];
    }
    else {
        [editedObject setValue:[NSNumber numberWithInteger:[[textField text] integerValue]] forKey:editedFieldKey];
    }

    [self.navigationController popViewControllerAnimated:YES];
}

Когда он выполняется, он пропускаетсначала оператор if запускает оператор else, затем вылетает и выдает ошибку: Unacceptable type of value for attribute: property = "firstName"; desired type = NSString; given type = __NSCFNumber; value = 0.

firstName - это строковый атрибут в моей модели данных.Я предполагаю, потому что это первое, если утверждение терпит неудачу, оно идет вперед и ожидает целое число?Я действительно не уверен.

Ответы [ 2 ]

2 голосов
/ 12 декабря 2011

ОК, поэтому, основываясь на значении nil в отладчике, позвольте мне объяснить, что происходит. В Objective-C любое сообщение, отправленное объекту nil, просто ничего не будет делать, а затем вернет nil (что имеет точно такое же значение памяти, как 0 и false и NO).

Итак, вы делаете это:

if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) {

Если editedObject равен nil, то valueForKey ничего не сделает и вернет nil. Затем вы отправляете isKindOfClass на nil, который также ничего не делает и возвращает nil. Внутри оператора if значение nil будет равно NO, что отправит вас в оператор else.

Где вы это делаете:

textField.text = [[editedObject valueForKey:editedFieldKey] stringValue];

editedObject равно nil, каскадное значение stringValue, возвращающее nil, и поэтому вы пытаетесь установить значение текстового поля равным nil, что недопустимо и приведет к сбою приложения.

Решение состоит в том, чтобы реструктурировать ваш код для проверки на nil. Вот как бы я написал ваш код:

// don't do anything for a nil value note this will detect editedObject being nil, or the result of valueForKey: being nil.
if (![editedObject valueForKey:editedFieldKey]) {
  return;
}

// figure out the string value
NSString *textFieldValue = [editedObject valueForKey:editedFieldKey];
if ([textFieldValue isKindOfClass:[NSNumber class]]) {
  textFieldValue = [(NSNumber *)textFieldValue stringValue]
}

// update the text field
textField.hidden = NO;
datePicker.hidden = YES;
textField.text = textFieldValue;
textField.placeholder = self.title;
[textField becomeFirstResponder];
0 голосов
/ 12 декабря 2011

Я решил ту же проблему с помощью приложения Core Data. Я также адаптировал приложение Core Data Books. Если вы заметили, что в исходном приложении они используют переменную BOOL (editingDate), чтобы решить, показывать ли средство выбора даты или нет. Я создал вторую переменную BOOL ('editTextView`) и просто изменил эти переменные BOOL в зависимости от того, что нужно редактировать. Это может быть не самый эффективный способ, но его легко программировать и легко следовать тому, что уже есть в Core Data Books.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...