【发布时间】:2014-05-20 01:32:50
【问题描述】:
我有一个用 C++ 和 Objective-C 编写的应用程序。 C++ 部分从远程摄像头接收数据并调用 Objective-C 回调(块)进行显示。 Objective-C 启用了 ARC。
显示视图加载时,我给C++部分设置了一个block,当数据到来时,C++会调用这个block来更新显示。
代码如下:
- (void)viewDidLoad
{
__weak CameraVC *weakSelf = self;
self.callback_func = ^int(int iWidth, int iHeight, int iDataLen, void *pData) {
NSData *data = [NSData dataWithBytes:pData length:iDataLen];
[weakSelf performSelectorOnMainThread:@selector(updateDisplayWithData:)
withObject:data waitUntilDone:YES];
return 0;
};
setDisplayCallback(self.callback_func);
}
- (void)updateDisplayWithData:(NSData *)data
{
self.imageView.image = [UIImage imageWithData:data];
}
setDisplayCallback() 是一个用于设置回调的 C++ 函数。
应用运行时,在xcode面板中显示应用内存使用情况,而且一直在增加,几个小时后,应用崩溃了,我认为是内存泄漏?
我已尝试评论代码:
// self.imageView.image = [UIImage imageWithData:data];
内存泄漏停止。
问题1是否存在导致此内存泄漏的保留周期?
我已尝试将块代码替换为:
self.callback_func = ^int(int iWidth, int iHeight, int iDataLen, void *pData) {
NSData *data = [NSData dataWithBytes:pData length:iDataLen];
[weakSelf performSelectorOnMainThread:@selector(updateDisplayWithData:)
withObject:data waitUntilDone:YES];
return 0;
};
到:
self.callback_func = ^int(int iWidth, int iHeight, int iDataLen, void *pData) {
NSData *data = [NSData dataWithBytesNoCopy:pData length:iDataLen freeWhenDone:YES];
[weakSelf performSelectorOnMainThread:@selector(updateDisplayWithData:)
withObject:data waitUntilDone:YES];
return 0;
};
内存泄漏问题减少了,但还是有。
问题2dataWithBytes和dataWithBytesNoCopy有什么区别?
更新
我尝试将这个单一文件设置为无ARC,并修改代码:
- (void)viewDidLoad
{
self.callback_func = ^int(int iWidth, int iHeight, int iDataLen, void *pData) {
@autoreleasepool {
NSData *data = [NSData dataWithBytes:pData length:iDataLen];
[self performSelectorOnMainThread:@selector(updateDisplayWithData:)
withObject:data waitUntilDone:YES];
}
return 0;
};
setDisplayCallback(self.callback_func);
}
内存使用稳定。我很好奇我的 ARC 版本代码有什么问题。
【问题讨论】:
标签: c++ objective-c memory-leaks automatic-ref-counting