Nic*_*ing 3 core-data objective-c ios
像许多iOS开发人员一样,我使用CoreData,就像许多使用CoreData的iOS开发人员一样,我有很难跟踪线程违规错误.我正在尝试实现一个调试策略,以便在CoreData并发规则被破坏时抛出异常.我的尝试在下面 - 我的问题是,这有效吗?它会产生误报吗?
简介:创建NSManagedObject时,请记下该线程.每当稍后访问某个值时,检查当前线程是否与创建线程相同,如果没有,则抛出异常.
#import "NSManagedObject+DebugTracking.h"
#import "NSObject+DTRuntime.h"
#import <objc/runtime.h>
#import "NSManagedObjectContext+DebugThreadTracking.h"
@implementation NSManagedObject (DebugTracking)
+(void)load {
[NSManagedObject swizzleMethod:@selector(willAccessValueForKey:) withMethod:@selector(swizzled_willAccessValueForKey:)];
[NSManagedObject swizzleMethod:@selector(initWithEntity:insertIntoManagedObjectContext:) withMethod:@selector(swizzled_initWithEntity:insertIntoManagedObjectContext:)];
}
- (__kindof NSManagedObject *)swizzled_initWithEntity:(NSEntityDescription *)entity
insertIntoManagedObjectContext:(NSManagedObjectContext *)context
{
NSManagedObject *object = [self swizzled_initWithEntity:entity insertIntoManagedObjectContext:context];
NSLog(@"Initialising an object of type: %@", NSStringFromClass([self class]));
object.debugThread = [NSThread currentThread];
return object;
}
-(void)swizzled_willAccessValueForKey:(NSString *)key {
NSThread *thread = self.debugThread;
if (!thread) {
NSLog(@"No Thread set");
} else if (thread != [NSThread currentThread]) {
[NSException raise:@"CoreData thread violation exception" format:@"Property accessed from a different thread than the object's creation thread. Type: %@", NSStringFromClass([self class])];
} else {
NSLog(@"All is well");
}
[self swizzled_willAccessValueForKey: key];
}
-(NSThread *)debugThread {
return objc_getAssociatedObject(self, @selector(debugThread));
}
-(void)setDebugThread:(NSThread *)debugThread {
objc_setAssociatedObject(self, @selector(debugThread), debugThread, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Run Code Online (Sandbox Code Playgroud)
Tom*_*ton 10
不,那不是个好主意.您将部分复制Apple构建到框架中的内容会遇到相当大的麻烦.
如果编辑目标的方案,则可以添加-com.apple.CoreData.ConcurrencyDebug 1到启动时传递的参数:
完成后,所有并发冲突都会导致立即崩溃.您会知道这是一个并发冲突,因为堆栈跟踪中的"留给我们的一切都是荣誉"消息:
您将看到导致并发冲突的确切代码行.
您可能需要添加一些其他核心数据的调试参数,com.apple.CoreData.SQLDebug并com.apple.CoreData.Logging.stderr为好.它们不会改变并发调试,但它们会使Xcode打印一条消息读取,CoreData: annotation: Core Data multi-threading assertions enabled这样你就可以知道它了.
| 归档时间: |
|
| 查看次数: |
841 次 |
| 最近记录: |