OSX的网络连接NSNotification?

4

当分配一个有效的IP地址时,我仅需要一个通知发布。我尝试使用SCReachability进行轮询,但那似乎效率低下。

有什么建议吗?这似乎应该很简单,但我已经苦苦挣扎几个小时,尝试让任何东西工作起来。

2个回答

11

我知道这有点老了,但所选答案并不理想。

SCReachability API可用于确定特定主机何时可达。如果你只想知道何时分配了有效的IP地址(而不是到目标IP的可行路由),则应查看SCDynamicStore* APIs。 这些函数允许您订阅系统配置存储以获得通知某些值发生更改的信息。 因此,要在任何接口上 IPv4 地址更改时获得通知,您需要执行以下操作(为方便阅读省略了错误检查)

  SCDynamicStoreRef dynStore;

  SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};

  dynStore = SCDynamicStoreCreate(kCFAllocatorDefault,
                                  CFBundleGetIdentifier(CFBundleGetMainBundle()),
                                  scCallback,
                                  &context);

    const CFStringRef keys[3] = {
        CFSTR("State:/Network/Interface/.*/IPv4")
    };
    CFArrayRef watchedKeys = CFArrayCreate(kCFAllocatorDefault,
                                         (const void **)keys,
                                         1,
                                         &kCFTypeArrayCallBacks);
    if (!SCDynamicStoreSetNotificationKeys(dynStore,
                                         NULL,
                                         watchedKeys)) 
  {
       CFRelease(watchedKeys);
        fprintf(stderr, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
        CFRelease(dynStore);
        dynStore = NULL;

        return -1;
    }
    CFRelease(watchedKeys);

    rlSrc = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynStore, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), rlSrc, kCFRunLoopDefaultMode);
    CFRelease(rlSrc);

你需要实现 scCallback 函数,它会在每次更改时被调用。此外,你需要在某个地方调用 CFRunLoopRun 以使代码运行。


1

你不必使用SCNetworkReachability轮询。你可以注册回调函数,系统会在网络状态改变时调用回调函数。这不是低效的。

请参考苹果的示例代码Reachability,它展示了如何将其集成到Objective-C应用程序中。该代码适用于iPhone,但我认为Reachability.{m,h}也可以在OS X上工作。

(参见苹果的示例代码SimpleReach。它已经五年了,但应该可以使用。)


我必须承认 - 我在这个例子上感到异常困惑。我非常新于 Cocoa,不确定如何将这个 C 语言示例集成到我的 ObjC 程序中。有提示吗? - Andrew J. Freyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接