在swift模块中,React本机桥有时是零

时间:2016-06-28 12:33:52

标签: objective-c swift react-native

我创建了一个swift模块,当从swift调用connect方法时,它开始侦听GCDAsyncUdpSocket

@objc(MyModule)
class MyModule: NSObject, GCDAsyncUdpSocketDelegate {
  var bridge: RCTBridge!
  var socket: GCDAsyncUdpSocket!

  func methodQueue() -> dispatch_queue_t {
    return dispatch_queue_create("com.mycompany.greatapp", DISPATCH_QUEUE_SERIAL)
  }

  @objc func connect(resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: methodQueue())

    //...start listening, etc
  }

  @objc func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
    bridge.eventDispatcher().sendAppEventWithName("got_msg", body: nil)
  }
}

我还创建了一个私有实现

#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(MyModule, NSObject)

RCT_EXTERN_METHOD(connect resolver:(RCTPromiseResolveBlock *)resolve
                  rejecter:(RCTPromiseRejectBlock *)reject)

@end

然而,偶尔bridge.eventDispatcher()展开nil并且无法广播该事件。任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:2)

这个Github问题让我得到了解决方案:https://github.com/facebook/react-native/issues/3454。原来这只发生在重装上。需要实现RCTInvalidating,然后清除invalidate中的任何悬空引用。这允许ARC正确清理您的本机模块并重新实例化RCTBridge

@objc(MyModule)
class MyModule: NSObject, GCDAsyncUdpSocketDelegate, RCTInvalidating {
  var bridge: RCTBridge!
  var socket: GCDAsyncUdpSocket!

  func invalidate() {
    self.socket = nil
  }

  func methodQueue() -> dispatch_queue_t {
    return dispatch_queue_create("com.mycompany.greatapp", DISPATCH_QUEUE_SERIAL)
  }

  @objc func connect(resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: methodQueue())

    //...start listening, etc
  }

  @objc func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
    bridge.eventDispatcher().sendAppEventWithName("got_msg", body: nil)
  }
}