多对等连接:在Objective-C ++中的浏览无提示地失败

时间:2019-04-14 21:35:54

标签: macos objective-c++ multipeer-connectivity

我正在尝试在Objective-C ++中编写Multipeer Connectivity应用程序的浏览器/发现端。我想我可以做广告,因为我可以使用发现(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];
}

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

1 个答案:

答案 0 :(得分:0)

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

我假设MultipeerConnectivity API在方法调用[browser startBrowsingForPeers]上创建了所需的线程和/或循环。不会。

此代码中的任何地方均未启动运行循环。另外,有趣的是,即使使用implied that it will,直接使用NSThread也不会启动运行循环:

  

您的应用程序既不创建也不显式管理NSRunLoop   对象。每个NSThread对象-包括应用程序的主对象   线程-根据需要自动为其创建了一个NSRunLoop对象。   如果您需要访问当前线程的运行循环,可以使用   类方法currentRunLoop。

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

  

当前线程的运行循环以默认模式运行(请参见默认   运行循环模式),直到使用CFRunLoopStop或全部停止运行循环为止   源和计时器将从默认的运行循环模式中删除。

那么阻止它运行的是CFRunLoopStop(CFRunLoopRef rl)

  

此功能强制rl停止运行并将控制权返回给   调用CFRunLoopRun或CFRunLoopRunInMode的函数   当前的运行循环激活。

当然,CFRunLoopStopCFRunLoopRef作为参数。您可以通过使用CFRunLoopGetCurrent来获取该信息,只需记住它是一个引用,并且可能随时过期。我认为您可以确定在运行循环中运行的回调中,运行循环不会死。但是我不会指望它会在之后留下来。实际上,在这种情况下,整个目的就是要在此时将其杀死。所以我希望它会消失。