我使用NSInputstream& NSOutputstream用于设置连接和发送数据.我的流对象具有打开和关闭流的功能.我使用以下代码:
@interface Stream() { NSInputStream *inputStream; NSOutputStream *outputStream; } -(id)init { self = [super init]; if (self) { inputStream = nil; outputStream = nil; } return self; } -(int)streamOpenWithIp:(NSString *)ip withPortNumber:(int)portNumber; { CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(kcfAllocatorDefault,(__bridge CFStringRef)ip,portNumber,&readStream,&writeStream); if(readStream && writeStream) { //Setup inpustream inputStream = (__bridge NSInputStream *)readStream; [inputStream setDelegate:self]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream open]; //Setup outputstream outputStream = (__bridge NSOutputStream *)writeStream; [outputStream setDelegate:self]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream open]; } } - (int)streamClose; { CFReadStreamSetProperty((__bridge CFReadStreamRef)(inputStream),kcfStreamPropertyShouldCloseNativeSocket,kcfBooleanTrue); CFReadStreamSetProperty((__bridge CFReadStreamRef)(outputStream),kcfBooleanTrue); //Close and reset inputstream [inputStream setDelegate:nil]; [inputStream close]; [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; inputStream = nil; //Close and reset outputstream [outputStream setDelegate:nil]; [outputStream close]; [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; outputStream = nil; }
当我多次打开和关闭流时,此代码工作正常.当我使用Instruments检查我的应用程序内存泄漏时,它说CFStreamCreatePairWithSocketToHost函数泄漏了72%的内存.有人知道我做错了什么吗?我无法弄明白.
解决方法
添加CFRelease((CFStreamRef)inputStream);和CFRelease((CFStreamRef)outputStream);在streamClose方法中.
当CFStreamCreatePairWithSocketToHost返回时,readStream和writeStream的所有权将传递给您:
Ownership follows the Create Rule in Memory Management Programming Guide for Core Foundation.
即使使用ARC,也需要明确释放Core Foundation对象:
The compiler does not automatically manage the lifetimes of Core Foundation objects; you must call CFRetain and CFRelease (or the corresponding type-specific variants) as dictated by the Core Foundation memory management rules (see Memory Management Programming Guide for Core Foundation).
或者,更改此行(以及outputStream的相应行):
inputStream = (__bridge NSInputStream *)readStream;
至:
inputStream = (__bridge_transfer NSInputStream *)readStream;
这是因为readStream具有ARC未知的优秀保留计数.通过给ARC指定此指针的所有权,您授予它在适当时间释放指针的权限.进一步阅读:1,2