我已经从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示例,我的代码是相同的,只有我添加了一个带有整数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语句失败了,它会向前推进一个期望整数?我真的不确定。
答案 0 :(得分:2)
好的,基于调试器中的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];
答案 1 :(得分:0)
我使用更多Core Data应用程序解决了同样的问题。我还改编了Core Data Books应用程序。如果您注意到,在原始应用中,他们使用BOOL变量(editingDate
)来决定是否显示日期选择器。我创建了第二个BOOL变量('editingTextView`),并根据需要编辑的内容更改那些BOOL变量。它可能不是最有效的方式,但它易于编程,并且易于遵循Core Data Books中已有的内容。