我对Cocoa开发很新,我可能不清楚ARC是如何工作的。
我的问题是,当我使用NSImageView时,它并没有像我想要的那样被释放,因此程序正在泄漏内存。
__block CMTime lastTime = CMTimeMake(-1, 1);
__block int count = 0;
[_imageGenerator generateCGImagesAsynchronouslyForTimes:stops
completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime,
AVAssetImageGeneratorResult result, NSError *error)
{
if (result == AVAssetImageGeneratorSucceeded)
{
if (CMTimeCompare(actualTime, lastTime) != 0)
{
NSLog(@"new frame found");
lastTime = actualTime;
}
else
{
NSLog(@"skipping");
return;
}
// place the image onto the view
NSRect rect = CGRectMake((count+0.5) * 110, 100, 100, 100);
// the problem is here!!! ImageView object gets allocated, but never released by the program even though I'm using ARC
NSImageView *imgV = [[NSImageView alloc] initWithFrame:rect];
[imgV setImageScaling:NSScaleToFit];
NSImage *myImage = [[NSImage alloc] initWithCGImage:image size:(NSSize){50.0,50.0}];
[imgV setImage:myImage];
[self.window.contentView addSubview: imgV];
}
if (result == AVAssetImageGeneratorFailed)
{
NSLog(@"Failed with error: %@", [error localizedDescription]);
}
if (result == AVAssetImageGeneratorCancelled)
{
NSLog(@"Canceled");
}
count++;
}];
因此,当我再次返回此块时,生成新图像并显示它们,一切都很完美,除了我的程序内存使用量增加了创建的视图数量。
如果有人可以帮助我,我会非常感激!谢谢!
答案 0 :(得分:2)
您的问题是,当您生成新的subviews
时,请不要删除subviews
- 请务必先删除NSArray *viewsToRemove = [self.contentView subviews];
for (NSView *v in viewsToRemove) {
[v removeFromSuperview];
}
之前的某些内容:
ARC
因此,您的问题实际上与NSImageView
的使用无关。每次创建contentView
并将其添加到contentView时,您都有责任在添加一系列新内容之前删除它们。请注意,将这些视图添加到ref count
会将{{1}}递增1并将其从contentView中删除会将ref计数减1,从而导致系统释放这些视图的内存使用量(因为没有否则在btw中保留你的观点。
答案 1 :(得分:1)
违规代码:
[self.window.contentView addSubview: imgV];
您已经分配了NSImageView。并继续将其添加到视图中。你永远不会删除它,这意味着视图创建了许多对同一对象的不同实例的引用,都分配了自己的内存。
解决方案:您需要跟踪视图,以确保以后可以将其删除。通常,我使用类扩展。
例如:
@interface ClassName() {
NSImageView* m_imgV;
}
@end
....
// place the image onto the view
NSRect rect = CGRectMake((count+0.5) * 110, 100, 100, 100);
if (m_imgV) {
[m_imgV removeFromSuperView];
}
m_imgV = [[NSImageView alloc] initWithFrame:rect];
[m_imgV setImageScaling:NSScaleToFit];
NSImage *myImage = [[NSImage alloc] initWithCGImage:image size:(NSSize){50.0,50.0}];
[m_imgV setImage:myImage];
[self.window.contentView addSubview:m_imgV];
答案 2 :(得分:0)
我整天都在与这个问题作斗争,终于找到了方法。出于某种原因,该程序希望我添加一个完整的函数,如下所示:
// remove all the view from the superview
// and clean up a garbage array
-(void) killAllViews
{
for (NSImageView *iv in _viewsToRemove)
{
[iv removeFromSuperview];
}
[_viewsToRemove removeAllObjects]; // clean out the array
}
其中_viewsToRemove是一个NSImageViews数组,每当我的块生成新图像并将它们添加到视图中时,我就会填充它们。
仍然不明白为什么只是将我的killAllViews方法中的纯代码添加到程序中就无法解决问题。现在我基本上做同样的事情,但只是调用这个方法。