可可,免费桥接和ARC

时间:2012-07-13 11:03:48

标签: objective-c cocoa stream inputstream tcpclient

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

首先,它是什么?第二,我试过两个,仍然无法发送消息。我跟着这个tutorial,我也发送了消息和流。我安装了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];

}

服务器很好,因为我已经尝试了示例代码并得到了响应。

你能帮助我吗?

1 个答案:

答案 0 :(得分:5)

正如H2CO3所提到的,这是一件ARC事。

如果您不知道ARC是什么,read this。总而言之,这是一种自动化内存管理内容(保留/释放语句等)的确定性方法,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_retainedCFBridgingRetain会将一个Objective-C指针强制转换为Core Foundation指针,并将所有权转移给您。   您有责任调用CFRelease或相关函数来放弃对象的所有权。
  •   
  • __bridge_transferCFBridgingRelease将非Objective-C指针移动到Objective-C,并将所有权转移到ARC。   ARC负责放弃对象的所有权。
  •   

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

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