我正在编写一个Multipeer应用程序,并且每当我的应用程序进入后台时都会发生一些随机崩溃。这可能是第一次或者直到第30次,所以我怀疑这是一个线程/时间问题,但我不确定如何解决它。
我将"消息发送到解除分配的实例"对于[MCNearbyServiceBrowser syncStopBrowsingForPeers],它不是公共方法,但可能在我调用stopBrowsingForPeers时调用。
我正在使用setUp / Start和Stop / shutdown方法,因此我可以在对等体之间启动/停止和重新启动会话。以下是相关代码。
我看不出我做错了什么,除非MultiPeer在幕后做一些我无法看到导致浏览器解除分配的事情。
@interface SSSSessionContainer : NSObject <MCSessionDelegate,
MCNearbyServiceAdvertiserDelegate,
MCNearbyServiceBrowserDelegate>
{
// Our peer ID used to advertise ourselves and identify ourselves
MCPeerID *_peerID ;
// Our set of sessions. One per peer keyed off of peer display name
NSMutableDictionary *_sessionList ;
// Our service advertiser that announces us to peers
MCNearbyServiceAdvertiser *_serviceAdvertiser ;
// Our browser that searches for nearby peers
MCNearbyServiceBrowser *_serviceBrowser ;
}
// Called when we are starting our message services. Either when app first starts or comes back from background
- (void) setupSessionServices ;
// Called when we are about to shutdown (go to background)
- (void) shutdownSessionServices ;
// Called when we start services because user changed Buddy Finder settings to ON
- (void) startServices ;
// Called when we stop services because user changed Buddy Finder settings to OFF
- (void) stopServices ;
和实施
- (void) setupSessionServices
{
// Create the service advertiser
_serviceAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:_peerID
discoveryInfo:nil
serviceType:kSSSServiceType];
_serviceAdvertiser.delegate = self;
// Create the service browser
_serviceBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:_peerID
serviceType:kSSSServiceType];
_serviceBrowser.delegate = self;
// should never happen, but make sure we start with no sessions
[_sessionList removeAllObjects] ;
}
- (void)shutdownSessionServices
{
// Nil out delegates
if ( _serviceAdvertiser != nil )
{
_serviceAdvertiser.delegate = nil;
}
if ( _serviceBrowser != nil )
{
_serviceBrowser.delegate = nil;
}
// nil out the advertiser and browser
_serviceAdvertiser = nil ;
_serviceBrowser = nil ;
}
- (void)startServices
{
if ( _serviceAdvertiser != nil )
{
[_serviceAdvertiser startAdvertisingPeer];
}
if ( _serviceBrowser != nil )
{
[_serviceBrowser startBrowsingForPeers];
}
}
- (void)stopServices
{
// Disconnect all of our current sessions
NSArray *allSessions = [_sessionList allValues] ;
for ( MCSession *session in allSessions )
{
[session disconnect];
}
// remove all session instances
[_sessionList removeAllObjects] ;
if ( _serviceAdvertiser != nil )
{
[_serviceAdvertiser stopAdvertisingPeer];
}
if ( _serviceBrowser != nil )
{
// This is the line that randomly crashes with zombie!
[_serviceBrowser stopBrowsingForPeers];
}
}
并在我的AppDelegate中:
- (void)applicationWillResignActive:(UIApplication *)application
{
// Stop our services
[[SSSSessionContainer sharedStore] stopServices] ;
// Shut down our services
[[SSSSessionContainer sharedStore] shutdownSessionServices] ;
}
最后,这是仪器的痕迹
0 Malloc +1 1 00:36.794.439 MyApp - [SSSSessionContainer setupSessionServices]
1保留+1 2 00:36.794.491 libsystem_sim_blocks.dylib _Block_copy_internal
2 Release -1 1 00:36.796.463 libdispatch.dylib _dispatch_client_callout
3保留+1 2 00:40.572.193 libsystem_sim_blocks.dylib _Block_copy_internal
4 Release -1 1 00:40.572.214 MyApp - [SSSAppDelegate applicationWillResignActive:]
5 Release -1 0 00:40.589.083 libdispatch.dylib _dispatch_client_callout
6 Zombie -1 0 0:40.590.426 MultipeerConnectivity - [MCNearbyServiceBrowser syncStopBrowsingForPeers]
因此,似乎applicationWillResignActive正在释放它,然后调用stopBrowsingForPeers,但它似乎是在我调用shutdown之前释放它。救命啊!
以下是崩溃日志的相关部分:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_platform.dylib 0x00000001036d1e34 _os_lock_corruption_abort + 0
1 libsystem_platform.dylib 0x00000001036d1e34 _OSSpinLockLockSlow + 125
2 CFNetwork 0x0000000102d77e86 CFNetServiceBrowserStopSearch + 60
3 MultipeerConnectivity 0x000000010016c947 -[MCNearbyServiceBrowser syncStopBrowsingForPeers] + 68
4 CoreFoundation 0x0000000102671d9c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
5 CoreFoundation 0x00000001025d451d _CFXNotificationPost + 2381
6 Foundation 0x0000000101f3f7fa -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
7 UIKit 0x0000000100f2e4bc -[UIApplication _handleApplicationSuspend:eventInfo:] + 847
8 UIKit 0x0000000100f38711 -[UIApplication handleEvent:withNewEvent:] + 1594
9 UIKit 0x0000000100f39216 -[UIApplication sendEvent:] + 79
10 UIKit 0x0000000100f29086 _UIApplicationHandleEvent + 578
11 GraphicsServices 0x000000010405671a _PurpleEventCallback + 762
12 GraphicsServices 0x00000001040561e1 PurpleEventCallback + 35
13 CoreFoundation 0x000000010259e679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
14 CoreFoundation 0x000000010259e44e __CFRunLoopDoSource1 + 478
15 CoreFoundation 0x00000001025c7903 __CFRunLoopRun + 1939
16 CoreFoundation 0x00000001025c6d83 CFRunLoopRunSpecific + 467
17 GraphicsServices 0x0000000104054f04 GSEventRunModal + 161
18 UIKit 0x0000000100f28e33 UIApplicationMain + 1010
19 MyApp 0x00000001000913b3 main + 115 (main.m:16)
20 libdyld.dylib 0x00000001036c85fd start + 1