Objective c 在“台风”中创建对象时崩溃

Objective c 在“台风”中创建对象时崩溃,objective-c,typhoon,Objective C,Typhoon,我在尝试实例化一个对象时,在typhoncomponentfactory.m中遇到一个崩溃-这一行在EXC_BAD_访问时崩溃: 279:[pool setObject:instance forKey:definition.key]; 或者有时候这个: 276:id instance = [pool objectForKey:definition.key]; 所有变量-池、实例、定义,都在调试器中查看崩溃的时间。在程序执行的早期(但不是更早,即相同的runloop),我已经设置了我的Typh

我在尝试实例化一个对象时,在typhoncomponentfactory.m中遇到一个崩溃-这一行在EXC_BAD_访问时崩溃:

279:[pool setObject:instance forKey:definition.key];
或者有时候这个:

276:id instance = [pool objectForKey:definition.key];
所有变量-池、实例、定义,都在调试器中查看崩溃的时间。在程序执行的早期(但不是更早,即相同的runloop),我已经设置了我的TyphonComponentFactory,并将其设置为默认工厂。有什么可能导致这种情况吗?我有一个模糊的理论,那就是这个工厂对来访者来说太晚了,但是。。。很弱

台风版本1.8.2。下面是大会:

#import "EndpointQueueAssembly.h"
#import "EndpointQueue.h"
#import "URLStorage.h"
#import "EndpointHTTPMethods.h"
#import "EndpointURLStrings.h"
#import "HTTPRequestOperationFactory.h"
#import "Services.h"
#import "ChatImageCheck.h"

@implementation EndpointQueueAssembly

-(id)endpointQueue
{

    return [TyphoonDefinition withClass: [EndpointQueue class] properties:^(TyphoonDefinition *definition) {

        [definition setScope:TyphoonScopeSingleton];

    }];

}

-(id)urlStorage
{

    return [TyphoonDefinition withClass: [URLStorage class]];

}

-(id)endpointHTTPMethods
{

    return [TyphoonDefinition withClass: [EndpointHTTPMethods class]];

}

-(id)chatImageCheck
{

    return [TyphoonDefinition withClass: [ChatImageCheck class]];

}

-(id)endpointURLStrings
{

    return [TyphoonDefinition withClass: [EndpointURLStrings class] properties:^(TyphoonDefinition *definition) {

        [definition injectProperty:@selector(urlStorage)];

    }];

}

-(id)httpRequestOperationFactory
{

    return [TyphoonDefinition withClass: [HTTPRequestOperationFactory class] properties:^(TyphoonDefinition* definition) {

        [definition injectProperty:@selector(endpointHTTPMethods)];

        [definition injectProperty:@selector(endpointURLStrings)];

    }];

}

-(id)services
{

    return [TyphoonDefinition withClass:[Services class] properties:^(TyphoonDefinition *definition) {

        [definition setScope:TyphoonScopeSingleton];

    }];

}

@end
堆栈跟踪,对于第276行上的崩溃:

Thread 65, Queue : NSOperationQueue 0x12434e90
#0  0x0473756b in -[__NSDictionaryM objectForKey:] ()
#1  0x0033c2dd in -[TyphoonComponentFactory sharedInstanceForDefinition:fromPool:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:276
#2  0x0033cb34 in -[TyphoonComponentFactory(TyphoonDefinitionRegisterer) objectForDefinition:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:315
#3  0x0033b01d in -[TyphoonComponentFactory componentForKey:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:151
#4  0x046a291d in __invoking___ ()
#5  0x046a282a in -[NSInvocation invoke] ()
#6  0x00335f69 in -[TyphoonBlockComponentFactory forwardInvocation:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/Block/TyphoonBlockComponentFactory.m:97
#7  0x0469e2da in ___forwarding___ ()
#8  0x0469e0ee in __forwarding_prep_0___ ()
#9  0x00022647 in +[CascadeItemRenderOperation isCurrentProfileWithDictionary:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/CascadeItemRenderOperation.m:166
#10 0x00022d3b in +[CascadeItemRenderOperation countOfUnreadChatsWithDictionary:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/CascadeItemRenderOperation.m:205
#11 0x00021c7c in +[CascadeItemRenderOperation renderWithDictionary:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/CascadeItemRenderOperation.m:79
#12 0x001002b2 in -[GrindrGridViewPreRenderOperation main] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Grindr/GrindrGridViewPreRenderOperation.m:38
#13 0x02d0dc79 in -[__NSOperationInternal _start:] ()
#14 0x02c8a9c8 in -[NSOperation start] ()
#15 0x02d0ff44 in __NSOQSchedule_f ()
#16 0x04d164d0 in _dispatch_client_callout ()
#17 0x04d02fe0 in _dispatch_async_redirect_invoke ()
#18 0x04d164d0 in _dispatch_client_callout ()
#19 0x04d04eb7 in _dispatch_root_queue_drain ()
#20 0x04d05127 in _dispatch_worker_thread2 ()
#21 0x05045dab in _pthread_wqthread ()
相关对象的价值:

self:TyphonBlockComponentFactory,包含注册表中可用的所有相关对象。 定义:“定义:class='AuthenticationDetails',key='AuthenticationDetails' 池:NSDictionary,0个键/值对 实例:id,未初始化的指针

这是当时主线程的堆栈-还包含台风引用:

Thread 1, Queue : com.apple.main-thread
#0  0x05081802 in __psynch_mutexwait ()
#1  0x05047945 in _pthread_mutex_lock ()
#2  0x050477ac in pthread_mutex_lock ()
#3  0x0443a498 in objc_sync_enter ()
#4  0x0033c288 in -[TyphoonComponentFactory sharedInstanceForDefinition:fromPool:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:275
#5  0x0033cb34 in -[TyphoonComponentFactory(TyphoonDefinitionRegisterer) objectForDefinition:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:315
#6  0x0033b01d in -[TyphoonComponentFactory componentForKey:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/TyphoonComponentFactory.m:151
#7  0x046a291d in __invoking___ ()
#8  0x046a282a in -[NSInvocation invoke] ()
#9  0x00335f69 in -[TyphoonBlockComponentFactory forwardInvocation:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Pods/Typhoon/Source/Factory/Block/TyphoonBlockComponentFactory.m:97
#10 0x0469e2da in ___forwarding___ ()
#11 0x0469e0ee in __forwarding_prep_0___ ()
#12 0x000735e7 in -[Profile(Custom) isMe] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Utils/Profile+Custom.m:74
#13 0x0022a0eb in -[Profile(GrindrGridViewHash) grindrGridViewHash] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/Profile+GrindrGridViewHash.m:84
#14 0x000ff3ed in -[GrindrGridViewPreRenderCache preRenderManagedObjectsForBackgroundExecution:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Grindr/GrindrGridViewPreRenderCache.m:105
#15 0x000ff174 in -[GrindrGridViewPreRenderCache preRenderManagedObjects:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Grindr/GrindrGridViewPreRenderCache.m:87
#16 0x00041c8f in -[GrindrGridView endUpdates] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/GrindrGridView.m:825
#17 0x002343d2 in -[CascadeDataSource controllerDidChangeContent:] at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Grindr/CascadeDataSource.m:137
#18 0x0276e347 in -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] ()
#19 0x02d0c049 in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke ()
#20 0x04709f04 in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
#21 0x04661efb in _CFXNotificationPost ()
#22 0x02c45e41 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#23 0x02670a13 in -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] ()
#24 0x0270ffaf in -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] ()
#25 0x0266beb8 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] ()
#26 0x0266b649 in -[NSManagedObjectContext processPendingChanges] ()
#27 0x0269a4cc in -[NSManagedObjectContext(_NestedContextSupport) _parentProcessSaveRequest:inContext:error:] ()
#28 0x02712a14 in __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke ()
#29 0x02694b81 in internalBlockToNSManagedObjectContextPerform ()
#30 0x04d164d0 in _dispatch_client_callout ()
#31 0x04d05439 in _dispatch_barrier_sync_f_slow_invoke ()
#32 0x04d164d0 in _dispatch_client_callout ()
#33 0x04d04726 in _dispatch_main_queue_callback_4CF ()
#34 0x0471343e in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
#35 0x046545cb in __CFRunLoopRun ()
#36 0x046539d3 in CFRunLoopRunSpecific ()
#37 0x046537eb in CFRunLoopRunInMode ()
#38 0x053ee5ee in GSEventRunModal ()
#39 0x053ee42b in GSEventRun ()
#40 0x03513f9b in UIApplicationMain ()
#41 0x0000e704 in main at /Users/nicklocking/Documents/primus-ios/NBFIOSCore/Shared/main.m:18
进一步更新:


看起来Typhone默认为TyphonScopeObjectGraph,这显然不是线程安全的。我们将所有非单例都切换到了TyphonScopePrototype,现在我们在第59行的TyphonCallStack-pop中遇到崩溃。似乎是某种例外,但调试器没有吐出任何有用的东西。

无法对您的帖子发表评论(声誉不够):

是的,如果您从不同的线程创建组件-这可能是崩溃的原因。Typhone现在不是线程安全的(在对象创建期间,我们使用的是非线程安全的NSMutableArray和NSMutableDictionary)

您可以通过将typhone调用包装到串行队列或synchronized语句中来修复它。。或者我们可以在Typhone内部完成(但这将是Typhone 2.0的功能-很难同时维护两个版本)

更新:


台风2.0现在是线程安全的

这是我们的解决方案,似乎效果不错:

#import "TyphoonComponentFactory+SwizzledObjectForDefinition.h"
#import "JRSwizzle.h"

@implementation TyphoonComponentFactory (SwizzledObjectForDefinition)

+ (void)swizzleMethods
{
    SEL objectForDefinitionSelector = sel_registerName("objectForDefinition:");
    [TyphoonComponentFactory jr_swizzleMethod: objectForDefinitionSelector
                                   withMethod: @selector(swizzledObjectForDefinition:)
                                        error: nil];
}

// Synchronize objectForDefinition
- (id)swizzledObjectForDefinition:(TyphoonDefinition *)definition
{
    @synchronized(self) {
        return [self swizzledObjectForDefinition:definition];
    }
}

@end

我们还将所有作用域声明为Singleton或Prototype。

您使用的是什么版本的Typhone?你的程序集看起来像什么?添加了程序集和版本。一些问题:当崩溃发生时,你能发布堆栈跟踪吗?(特别是台风框架部分,从坠机线到坠机地点)。
实例
定义
有哪些值?台风正试图建造哪些物体?你在台风中看到几条线了吗?(台风应该主要是线程安全的,但事故会发生)。添加堆栈跟踪和所有其他信息。在这个例子中,我看到主线程也在访问Typhone的东西,但情况并非总是如此。我们已经找到了问题的线索——默认情况下,所有内容都显示为TyphonScopeObjectGraph。由于这不是线程安全的,而且我们在后台做了很多事情,我们看到了很多崩溃。这是我们这边的已知问题还是配置问题?啊。好的,我们将尝试将typhoncomponentfactory-objectForDefinition:包装到@synchronized块中。将所有调用放入串行队列对我们来说不是一个好的解决方案,因为我们使用了许多创建这些对象的NSOperationQueue对象。根据您的测试,仅仅将所有作用域作为Singleton或Prototype是不够的?不,它崩溃得很厉害。