我有一个对象ECClient
,它由ECSignalingChannel
中的字典以及ECRoom
保留。
不幸的是,ECClient
在被释放时崩溃了。
我猜它崩溃的原因是因为它是由所有者(ECRoom
)和字典(ECSignalingChannel
中的一个属性)发布的。
以下是ECClient
初始化的位置:
// ECSingalingChannel.m
- (void)onSocketSignalingMessage:(NSDictionary *)msg type:(NSString *)type {
if (!signalingDelegate) {
signalingDelegate = [_roomDelegate clientDelegateRequiredForSignalingChannel:self];
[signalingDelegate setStreamId:message.streamId];
[signalingDelegate setPeerSocketId:message.peerSocketId];
[self setSignalingDelegate:signalingDelegate];
}
}
// ECRoom.m
- (id<ECSignalingChannelDelegate>)clientDelegateRequiredForSignalingChannel:(ECSignalingChannel *)channel {
id client = [[ECClient alloc] initWithDelegate:self andPeerFactory:_peerFactory];
return client;
}
// ECRoom.m
- (void)publish:(ECStream *)stream {
// Create a ECClient instance to handle peer connection for this publishing.
// It is very important to use the same factory.
publishClient = [[ECClient alloc] initWithDelegate:self
peerFactory:stream.peerFactory
streamId:nil
peerSocketId:nil
options:[self getClientOptionsWithStream:stream]];
//....
// Ask for publish
[_signalingChannel publish:options signalingChannelDelegate:publishClient];
}
// ECRoom.m
- (void)signalingChannel:(ECSignalingChannel *)channel didRequestPublishP2PStreamWithId:(NSString *)streamId
peerSocketId:(NSString *)peerSocketId {
ECClient *client = [[ECClient alloc] initWithDelegate:self
peerFactory:_peerFactory
streamId:streamId
peerSocketId:peerSocketId
options:[self getClientOptionsWithStream:self.publishStream]];
[p2pClients setValue:client forKey:peerSocketId];
[_signalingChannel publishToPeerID:peerSocketId signalingChannelDelegate:client];
}
以下是NSZombie的日志:
(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x40)
frame #0: 0x000000010257c530 WebRTC`___lldb_unnamed_symbol6507$$WebRTC + 120
frame #1: 0x000000010260bf74 WebRTC`___lldb_unnamed_symbol11131$$WebRTC + 56
frame #2: 0x000000010260bef0 WebRTC`___lldb_unnamed_symbol11129$$WebRTC + 116
frame #3: 0x000000010260a444 WebRTC`___lldb_unnamed_symbol11075$$WebRTC + 12
frame #4: 0x000000010260a424 WebRTC`___lldb_unnamed_symbol11073$$WebRTC + 60
frame #5: 0x000000010258bf64 WebRTC`___lldb_unnamed_symbol7191$$WebRTC + 36
frame #6: 0x000000010258e8b4 WebRTC`___lldb_unnamed_symbol7257$$WebRTC + 80
frame #7: 0x0000000184616ef4 libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 148
frame #8: 0x0000000184624990 libobjc.A.dylib`objc_destructInstance + 68
frame #9: 0x000000018546c3f8 CoreFoundation`-[NSObject(NSObject) __dealloc_zombie] + 136
* frame #10: 0x000000010183a67c ALCircallSDK`__destroy_helper_block_((null)=0x00000001c5c73880) at ECClient.m:245
frame #11: 0x0000000184df0a5c libsystem_blocks.dylib`_Block_release + 152
frame #12: 0x0000000101a0d220 libdispatch.dylib`_dispatch_client_callout + 16
frame #13: 0x0000000101a11db0 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1180
frame #14: 0x0000000185407070 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
frame #15: 0x0000000185404bc8 CoreFoundation`__CFRunLoopRun + 2272
frame #16: 0x0000000185324da8 CoreFoundation`CFRunLoopRunSpecific + 552
frame #17: 0x0000000187307020 GraphicsServices`GSEventRunModal + 100
frame #18: 0x000000018f30578c UIKit`UIApplicationMain + 236
frame #19: 0x000000010095e630 ALDemoApp`main(argc=1, argv=0x000000016f4c79b0) at main.m:14
frame #20: 0x0000000184db5fc0 libdyld.dylib`start + 4
(lldb)
如何避免这种过度释放?