可可,免费桥接和ARC

88f*_*tos 0 cocoa inputstream objective-c stream tcpclient

我想做一个简单的TCP客户端.但我收到一个错误.当我做 inputStream = (NSInputStream *)readStream;,outputStream = (NSOutputStream *)writeStream;它建议我引入前缀__bridge或_ bridge _transfer.

首先,它是什么?第二,我试过两个,仍然无法发送消息.我按照本教程,我也发送了消息和流.我安装了Wireshark并且已经调用了send消息,但它没有向ip发送任何数据包.

我刚刚在这里发布了initNetworkCommunication,因为我收到了"网桥"错误.

- (void) initNetworkCommunication {

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"54.xxx.xxx.xxx", 1333, &readStream, &writeStream);

    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

}
Run Code Online (Sandbox Code Playgroud)

服务器很好,因为我已经尝试了示例代码,我收到了回复.

你能帮助我吗?

Amy*_*all 5

正如H2CO3所提到的那样,这是一件ARC的事情.

如果您不知道ARC是什么,请阅读此内容.总而言之,这是一种自动化内存管理内容(保留/释放语句等)的确定性方法,Objective-C程序员以前必须手动完成.它非常值得使用,并且几乎没有缺点.但是,它确实有一些问题.

ARC不适用于Core Foundation对象.他们仍然遵守旧规则,你必须自己做内存管理.ARC仅适用于Objective-C对象.但是,一些Core Foundation对象实际上是免费桥接到它们的Cocoa等价物.您在代码示例中使用免费桥接,创建一个CFReadStreamRef,然后使用它作为一个NSInputStream.

所以你会怎么做?Apple的文档说如下:

如果在Objective-C和Core Foundation风格的对象之间进行转换,则需要使用强制转换(在objc/runtime.h中定义)或Core Foundation样式宏(在中定义)来告诉编译器对象的所有权语义. NSObject.h):

  • __bridge 在Objective-C和Core Foundation之间传输指针而不转移所有权.
  • __bridge_retained或者CFBridgingRetain将一个Objective-C指针强制转换为Core Foundation指针,并将所有权转移给您.您有责任调用CFRelease或相关函数来放弃对象的所有权.
  • __bridge_transfer或者CFBridgingRelease将非Objective-C指针移动到Objective-C,并将所有权转移到ARC.ARC负责放弃对象的所有权.

您正在从Core Foundation迁移到Objective-C,因此请忽略第二个要点(即向另一个方向前进).问题是你想要发生什么 - 如果在转移之后你想将该对象交给ARC,只使用Objective-C方面,并让ARC处理内存管理,请使用__bridge_transfer.根据您的代码示例,这可能是您想要的.

如果您只是使用__bridge,或者如果您不使用ARC,则需要自己清理对象,使用CFRelease()或发送release消息(后者仅在您不使用ARC时才有效).