设置核心数据对象的标量属性时的 EXC_BAD_ACCESS (IOS 5)

Posted

技术标签:

【中文标题】设置核心数据对象的标量属性时的 EXC_BAD_ACCESS (IOS 5)【英文标题】:EXC_BAD_ACCESS when setting scalar property of Core Data object (IOS 5) 【发布时间】:2012-07-21 05:41:58 【问题描述】:

我在 ios 5.1 模拟器中运行以下代码:

Table* sparkFront =
  [NSEntityDescription insertNewObjectForEntityForName:@"Table"
                                inManagedObjectContext:_context];
NSLog(@"%@", sparkFront);
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Table"
                                          inManagedObjectContext:_context];
NSDictionary* dict = [entity propertiesByName];
for (NSObject* key in [dict allKeys])

  NSLog(@"%@", key);

sparkFront.columnValuesAddress = 0x606;

此代码在最后一行出现 EXC_BAD_ACCESS 崩溃。 Table 对象是一个 Core Data 对象,实现如下:

@interface Table : NSManagedObject
@property (nonatomic) int32_t columnValuesAddress;
@end

我知道 Core Data 本身并不做标量类型,但这是一个仅限 IOS 5+ 的应用程序,我的印象是取消/装箱是自动完成的。上面代码在崩溃前的输出表明我的上下文和实体是好的:

2012-07-20 22:17:52.714 otest[95147:7b03] <NSManagedObject: 0x9c87b20> (entity: Table; id: 0x9c86a80 <x-coredata:///Table/t2C0D90D5-E381-4BD0-B65D-8FC83C6D50DB2> ; data: 
columnValuesAddress = 0;
)
2012-07-20 22:17:52.716 otest[95147:7b03] columnValuesAddress

崩溃后,问题报告显示如下:

Application Specific Information:
objc_msgSend() selector name: isNSNumber__
Simulator libSystem was initialized out of order.


Thread 0 Crashed:
0   libobjc.A.dylib                 0x00635098 objc_msgSend + 12
1   CoreData                        0x05c2e833 _PFManagedObject_coerceValueForKeyWithDescription + 483
2   CoreData                        0x05bfe3d1 _sharedIMPL_setvfk_core + 209
3   CoreData                        0x05c16687 _svfk_0 + 39
4   ECMCalTests                     0x0187f8f1 -[ECMCalTests testInsertRecords] + 849 (ECMCalTests.m:73)
5   CoreFoundation                  0x003f74ed __invoking___ + 29
6   CoreFoundation                  0x003f7407 -[NSInvocation invoke] + 167
7   SenTestingKit                   0x201039c4 -[SenTestCase invokeTest] + 184
8   SenTestingKit                   0x20103868 -[SenTestCase performTest:] + 183
9   SenTestingKit                   0x201034a9 -[SenTest run] + 82
10  SenTestingKit                   0x20106db2 -[SenTestSuite performTest:] + 106
11  SenTestingKit                   0x201034a9 -[SenTest run] + 82
12  SenTestingKit                   0x20106db2 -[SenTestSuite performTest:] + 106
13  SenTestingKit                   0x201034a9 -[SenTest run] + 82
14  SenTestingKit                   0x20105e97 +[SenTestProbe runTests:] + 174
15  CoreFoundation                  0x00492d51 +[NSObject performSelector:withObject:] + 65
16  otest                           0x0000231c 0x1000 + 4892
17  otest                           0x000025be 0x1000 + 5566
18  otest                           0x00002203 0x1000 + 4611
19  otest                           0x00001f8d 0x1000 + 3981
20  otest                           0x00001f31 0x1000 + 3889

我做错了什么?

更新:我根据核心数据教程实现了属性的 setter/getter。它仍然崩溃。它永远不会在设置器中遇到断点,因此它甚至在调用设置器之前就崩溃了。我是否遇到了 Apple 代码中的错误?

@interface Table : NSManagedObject

  int32_t columnValuesAddress;

@property (nonatomic) int32_t columnValuesAddress;
@end

@implementation Table

- (int32_t)columnValuesAddress

  [self willAccessValueForKey:@"columnValuesAddress"];
  int32_t address = columnValuesAddress;
  [self didAccessValueForKey:@"columnValuesAddress"];
  return address;


- (void)setColumnValuesAddress:(int32_t)address

  [self willChangeValueForKey:@"columnValuesAddress"];
  columnValuesAddress = address;
  [self didChangeValueForKey:@"columnValuesAddress"];


- (void)setNilValueForKey:(NSString *)key

  if ([key isEqualToString:@"columnValuesAddress"])
  
    self.columnValuesAddress = 0;
  
  else
  
    [super setNilValueForKey:key];
  


@end

【问题讨论】:

尝试自己装箱和拆箱,看看它是否仍然崩溃 哪里说 iOS 5 会自动(取消)装箱? 这就是我的意思。 【参考方案1】:

在实体编辑器中,您需要设置您的类。它是在您使用文件模板创建核心数据类文件时为您设置的。我创建了一个没有模板的类文件,因此没有设置类,所以我收到了这些错误。如果它可以看到该类并看到您将其指定为assign,它只会自动装箱和取消装箱。

【讨论】:

【参考方案2】:

我创建了一个全新的项目,从头开始重新创建模型,并从旧项目中复制了测试代码。这个新项目运行良好。我不知道为什么旧项目不起作用,但至少有一个解决方案。

【讨论】:

以上是关于设置核心数据对象的标量属性时的 EXC_BAD_ACCESS (IOS 5)的主要内容,如果未能解决你的问题,请参考以下文章

仅在某些设备上出现核心数据标量错误

CoreData Int32 标量问题

如何使用核心数据整数 64 属性?

iPhones SDK:使用核心数据设置关系属性对象?

尝试访问托管对象属性时的 EXC_BAD_ACCESS

索引对象点符号方法给出标量属性