5

MultiPeer Connectivity フレームワークを使用するアプリケーションがあります。アプリケーションが AppDelegate でアクティブになるたびに、新しい MCSession を MCNearbyBrowserService に作成し、MCNearbyAdvertiserService を呼び出してブラウジングを開始し、広告を開始します。次に、アプリケーションが AppDelegate で非アクティブになるたびに、ブラウジングと広告を停止し、すべてを nil に設定します。MCNearbyBrowserService がその syncQueue でクラッシュを引き起こすことがわかりました。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -    [__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'
*** First throw call stack:
(0x2de3ee8b 0x381396c7 0x2dd7caef 0x2dd7c8b3 0x2f648167 0x2f6493af 0x3861e103 0x38622e77 0x3861ff9b 0x38623751 0x386239d1 0x3874ddff 0x3874dcc4)
libc++abi.dylib: terminating with uncaught exception of type NSException

時々アプリが再開したとき。

applicationDidBecomeActive のコードは次のとおりです。

self.myIdentifier = [[MCPeerID alloc] initWithDisplayName:[self.class createHash:20]];

self.mainSession = [[MCSession alloc] initWithPeer:self.myIdentifier];
self.mainSession.delegate = self;

peerAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.myIdentifier discoveryInfo:nil serviceType: service];
peerAdvertiser.delegate = self;
peerBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.myIdentifier serviceType: service];
peerBrowser.delegate = self;

acceptReset = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(reset) userInfo:nil repeats:YES];
acceptPosts = true;
[peerBrowser startBrowsingForPeers];
[peerAdvertiser startAdvertisingPeer];

self.isBrowsing = true;

そして、ここにapplicationWillResignActiveの私のコードがあります:

[acceptReset invalidate];
[peerAdvertiser stopAdvertisingPeer];
[peerBrowser stopBrowsingForPeers];
[self.mainSession disconnect];
self.mainSession = false;
self.isBrowsing = false;

完全なコードはここで見ることができます: http://pastebin.com/E3wY6U4N

4

1 に答える 1

3

この問題に遭遇したときのことを覚えています。手っ取り早い解決策は、デリゲートをなくして、ブラウザーと広告主を解放することでした。したがって、App Delegate がそれぞれに強力なプロパティを持っていると仮定すると、セットアップ メソッドは次のようになります。

self.peerAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.myIdentifier discoveryInfo:nil serviceType: service];
self.peerAdvertiser.delegate = self;

self.peerBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.myIdentifier serviceType: service];
self.peerBrowser.delegate = self;

そして、アプリがバックグラウンドに入ると (またはブラウジング/広告を停止したい場合):

self.peerAdvertiser.delegate = nil;
[self.peerAdvertiser stopAdvertisingPeer];
self.peerAdvertiser = nil;

self.peerBrowser.delegate = nil;
[self.peerBrowser stopBrowsingForPeers];
self.peerBrowser = nil;

[self.mainSession disconnect];

MCPeerIDまた、マルチピア接続には古いピアを発見する習慣があり、再起動するたびに「以前の自分」を発見することになるため、アプリを起動するたびに新しいを作成しないことをお勧めします.

于 2014-06-25T00:20:34.290 に答える