检测核心数据中的字符串或整数

问题描述 投票:1回答:2

我已经从Core Data Books示例中为我的应用程序内置了一些Core Data支持。该示例使用日期和字符串。但是,我尝试添加添加和编辑Integer值的功能。

//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]])无法正常工作。

如果您确实查看了Apple的CoreDataBooks示例,我的代码是相同的,只是我添加了一个带Integer 16的字段。

编辑

[在第一个if语句上设置断点并在控制台中返回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是我的数据模型中的字符串属性。我猜是因为第一个if语句失败,所以它前进了一个期望整数?我真的不确定。

iphone objective-c ipad core-data
2个回答
0
投票

我通过更多的Core Data应用解决了相同的问题。我还改编了Core Data Books应用程序。如果您注意到,在原始应用中,他们使用BOOL变量(editingDate)决定是否显示日期选择器。我创建了第二个BOOL变量('editingTextView`),然后根据需要编辑的内容更改这些BOOL变量。这可能不是最有效的方法,但是它很容易编程,也很容易遵循Core Data Books中已经存在的内容。


2
投票

确定,因此基于调试器中的值为nil,请允许我解释发生了什么。在Objective-C中,任何发送到nil对象的消息都将不执行任何操作,然后返回nil(恰好与0falseNO具有相同的内存值)。

所以您正在这样做:

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

如果editedObjectnil,则valueForKey将不执行任何操作并返回nil。然后,您将isKindOfClass发送到nil,这也将不执行任何操作并返回nil。在if语句中,nil将计算为NO,将您带到else语句。

您在哪里这样做:

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

[editedObjectnil,级联为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];