Orb*_*sii 1 core-data objective-c nsmanagedobject ios
我在一个简单的Core Data项目中崩溃了.
我用Core Data创建了一个新的空iPhone项目.两个实体被添加到数据模型中,它们之间具有一对一的反向关系.两者都有自动生成的NSManagedObject子类.实体名称和类都设置在两者上.
DBMove
attribute: moveValue:Integer16
relationship: newPosition -> DBPosition (inverse: move)
DBPosition
attribute: positionValue:Integer16
relationship: move -> DBMove (inverse: newPosition)
Run Code Online (Sandbox Code Playgroud)
有一个自定义视图控制器,可以创建DBMove和DBPosition.然后它设置它们之间的反比关系并保存它.从app delegate中检索托管对象上下文; 我认为这是安全的,因为[NSThread isMultiThreaded]返回false.
- (void)newEntries
{
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
DBPosition *newPos = [NSEntityDescription
insertNewObjectForEntityForName:@"DBPosition"
inManagedObjectContext:context];
newPos.positionValue = [NSNumber numberWithInt:5];
DBMove *newMove = [NSEntityDescription
insertNewObjectForEntityForName:@"DBMove"
inManagedObjectContext:context];
newMove.moveValue = [NSNumber numberWithInt:2];
newPos.move = newMove;
NSError *error;
if (![context save:&error]) {
NSLog(@"Save error: %@", [error localizedDescription]);
}
}
Run Code Online (Sandbox Code Playgroud)
视图控制器然后提取所有DBMoves.他们的Integer16属性按预期输出. [编辑]访问关系会导致main :: @ autoreleasepool中的EXC_BAD_ACCESS在循环遍历所有获取结果后的某个时间发生.崩溃之前,以前程序中数据库中DBMove和DBPosition的所有条目都运行正确,然后是来自我的ViewController init的NSLogs; 崩溃似乎延迟了.它大约每5个程序运行中就有4个出现.[结束编辑]
- (void)printMoves
{
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"DBMove"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (DBMove *move in fetchedObjects) {
DBPosition *newPos = move.newPosition; // <--- all's well without this reference!
NSLog(@"Move : %d", [move.moveValue intValue]);
NSLog(@"Position : %d", [newPos.positionValue intValue]);
}
}
Run Code Online (Sandbox Code Playgroud)
NSZombieEnabled = YES会导致程序无误地运行并打印预期值.在整个执行过程中,我的上下文似乎是相同的.
这是堆栈跟踪:
#0 0x018300b2 in objc_msgSend ()
#1 0x00256ffc in -[_CDSnapshot dealloc] ()
#2 0x0025573d in -[_CDSnapshot release] ()
#3 0x00260384 in -[NSManagedObject(_NSInternalMethods) _clearRawPropertiesWithHint:] ()
#4 0x0026018b in -[NSFaultHandler turnObject:intoFaultWithContext:] ()
#5 0x002607ba in -[NSManagedObject dealloc] ()
#6 0x00257b88 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:] ()
#7 0x00232fe1 in _performRunLoopAction ()
#8 0x01a654ce in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#9 0x01a6541f in __CFRunLoopDoObservers ()
#10 0x01a43344 in __CFRunLoopRun ()
#11 0x01a42ac3 in CFRunLoopRunSpecific ()
#12 0x01a428db in CFRunLoopRunInMode ()
#13 0x038fe9e2 in GSEventRunModal ()
#14 0x038fe809 in GSEventRun ()
#15 0x0058ed3b in UIApplicationMain ()
#16 0x0000396d in main at /Users/brian/devel/test2-CoreData/test2-CoreData/main.m:16
Run Code Online (Sandbox Code Playgroud)
当我在空的新项目上检查"核心数据"时,所有核心数据设置都来自标准包含.
据推测,我过度释放了一个托管对象,但在哪里?
Orb*_*sii 10
newPosition用"new" 开始属性就是问题所在!它被翻译成一个名为"newPosition"的存取器的属性,在转换为ARC发行说明时禁止使用:
为了允许与手动保留释放代码进行互操作,ARC对方法命名施加了约束:
您不能为访问者提供以new开头的名称.这反过来意味着你不能,例如,声明一个名称以new开头的属性,除非你指定一个不同的getter:
Run Code Online (Sandbox Code Playgroud)// Won't work: @property NSString *newTitle; // Works: @property (getter=theNewTitle) NSString *newTitle;
可以像示例中那样编写自定义getter,但是选择更好的名称并继续使用内置工具生成类文件要容易得多.
请注意,编译器将在使用@synthesize时捕获此错误,但不会在@dynamic中捕获此错误,如在自动生成的NSManagedObject类中使用的那样.
| 归档时间: |
|
| 查看次数: |
1334 次 |
| 最近记录: |