多人连接:在 Objective-C++ 中浏览静默失败

Multipeer Connectivity: Browsing in Objective-C++ Silently Fails

我正在尝试为 Objective-C++ 中的多点连接应用程序编写 browser/discovery 端。我想我可以做广告,据我所知,因为我可以使用 Discovery (https://itunes.apple.com/us/app/discovery-dns-sd-browser/id1381004916?mt=12) 看到它。但是我的浏览器什么也看不到。我做错了什么?

#include <iostream>
#include <thread>

#import <MultipeerConnectivity/MultipeerConnectivity.h>

@interface Bowser : NSObject<MCNearbyServiceBrowserDelegate>

- (void)browser:(MCNearbyServiceBrowser *)browser 
    foundPeer:(MCPeerID *)peerID 
    withDiscoveryInfo:(NSDictionary *)info;

- (void)browser:(MCNearbyServiceBrowser *)browser 
    lostPeer:(MCPeerID *)peerID;

@end

@implementation Bowser

- (void)browser:(MCNearbyServiceBrowser *)browser 
    foundPeer:(MCPeerID *)peerID 
    withDiscoveryInfo:(NSDictionary *)info {
    std::cout << "Hello" << std::endl;
}

- (void)browser:(MCNearbyServiceBrowser *)browser 
    lostPeer:(MCPeerID *)peerID {
    std::cout << "Goodbye" << std::endl;
}

@end

int main() {
    MCPeerID* peerid = [[MCPeerID alloc] initWithDisplayName:@"PeerId"];
    Bowser* delegate = [[Bowser alloc] init];

    MCNearbyServiceBrowser* browser = [MCNearbyServiceBrowser alloc];
    [browser initWithPeer:peerid serviceType:@"m"];

    browser.delegate = delegate;

    [browser startBrowsingForPeers];

    using namespace std::chrono_literals;
    std::this_thread::sleep_for(10s);

    [browser stopBrowsingForPeers];
}

关于如何调试正在发生的事情的建议也很有用。有人...?

我(终于)明白了。 MultipeerConnectivity 需要一个 运行 循环。这是文档中的而不是

我假设 MultipeerConnectivity API 在方法调用 [browser startBrowsingForPeers] 时创建了它所需的线程 and/or 循环。它没有。

此代码中没有任何地方开始了 运行 循环。此外,有趣的是,直接使用 NSThread 不会启动 运行 循环,即使它是 implied that it will:

Your application neither creates or explicitly manages NSRunLoop objects. Each NSThread object—including the application’s main thread—has an NSRunLoop object automatically created for it as needed. If you need to access the current thread’s run loop, you do so with the class method currentRunLoop.

创建 运行 循环(并启动它)的是 CFRunLoopRun():

The current thread’s run loop runs in the default mode (see Default Run Loop Mode) until the run loop is stopped with CFRunLoopStop or all the sources and timers are removed from the default run loop mode.

那么,阻止它的是CFRunLoopStop(CFRunLoopRef rl):

This function forces rl to stop running and return control to the function that called CFRunLoopRun or CFRunLoopRunInMode for the current run loop activation.

当然,CFRunLoopStop 需要一个 CFRunLoopRef 作为参数。您可以使用 CFRunLoopGetCurrent 获得它,请记住它只是一个参考,随时可能过期。我认为您可以非常确定 运行 循环不会在您处于 运行 循环中 运行ning 的回调中时结束。但我不会指望它会在之后留下来。事实上,在这种情况下,重点是在此时杀死它;所以我希望它会消失。