iOS中的CFStreamCreatePairWithSocketToHost内存泄漏

前端之家收集整理的这篇文章主要介绍了iOS中的CFStreamCreatePairWithSocketToHost内存泄漏前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用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

猜你在找的iOS相关文章