CFStreamCreatePairWithSocketToHost中的内存泄漏iOS
问题描述:
我使用NSInputstream
& NSOutputstream
来设置连接并发送数据。我的流对象具有打开和关闭流的功能。我使用下面的代码:CFStreamCreatePairWithSocketToHost中的内存泄漏iOS
@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), kCFStreamPropertyShouldCloseNativeSocket, 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;
}
当我多次打开和关闭流时,此代码正常工作。当我用仪器检查我的应用程序内存泄漏时,它表示功能CFStreamCreatePairWithSocketToHost
将内存泄漏了72%。有人知道我在做什么错吗?我无法弄清楚。
答
在streamClose
方法中加上CFRelease((CFStreamRef)inputStream);
和CFRelease((CFStreamRef)outputStream);
。
当CFStreamCreatePairWithSocketToHost
回报的readStream
和writeStream
所有权被传递到你:
Ownership follows the Create Rule in Memory Management Programming Guide for Core Foundation.
核心基础对象需要使用ARC时甚至明确释放:
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
我在我的项目中使用自动引用计数,所以我不能使用发布。它是否为我自动完成? – 2013-05-02 07:05:43
检查我的更新 – Mar0ux 2013-05-02 07:14:33
它的工作!没有内存泄漏了。我认为你的意思是NSInputStream而不是NSString在你的答案? – 2013-05-02 09:25:57