避免“潜在泄漏”的惯用语是:带有“远距离”的警告发布?

发布于 2024-10-19 04:20:25 字数 1478 浏览 7 评论 0原文

处理大图像的动画,您可以这样做:只需为每个大图像分配内存...

NSArray *imagesForLargeAnimation;

#define IMG(X) [[UIImage alloc] \
  initWithContentsOfFile:[[NSBundle mainBundle] \
    pathForResource:@X ofType:@"tif"]]

imagesForLargeAnimation  = [[NSArray alloc] initWithObjects:
                    IMG("01"),
// (since we are allocing that image, of course we must release it eventually.)
                    IMG("02"),
                    IMG("03"),
                    ....
                    IMG("42"),
                    nil];

animationArea.animationImages = imagesForLargeAnimation;
//blah blah...

稍后,一旦动画停止并且不再在屏幕上显示,即可清理您所拥有的内存这样做:

-(void) cleanUpTheMemoryInTheBigAnimation
 {
 //blah blah..

 // for each of those big images in the array, release the memory:
 for (UIImage *uu in imagesForLargeAnimation)
    [uu release];

 // release the array itself
 [imagesForLargeAnimation release];
 imagesForLargeAnimation = nil;

现在,这一切都完美高效地工作,如果您重复使用不同的大型动画,它不会泄漏或过度使用内存。

唯一的问题是,您当然会收到 clang 警告:“第 69 行分配的对象的潜在泄漏”,实际上您会收到大量这些警告,每个分配一个。

避免这些警告并使其更安全、更严格的最佳习惯用法是什么?

有谁知道吗?

例如,如果您使用 autorelease,那么在上面的代码示例中,您将在 IMG 定义中使用 autorelease...

...事实上,当您释放 NSArray (即 [imagesForLargeAnimation release] )...那它会自动释放数组中的所有对象吗?这是正确的吗?或者??

(或者我应该使用某种 newBlah 函数来放入图像,或者..??)

如果有人知道这里避免“潜在泄漏”的正确方法,谢谢!

{PS 提醒一下,基本上永远不要使用 imageNamed:,这是没有希望的:它只适合小型 UI 使用类型的图像。切勿使用 imageNamed!}

Dealing with an animation of large images, you can do this: Simply alloc memory for each of the large images...

NSArray *imagesForLargeAnimation;

#define IMG(X) [[UIImage alloc] \
  initWithContentsOfFile:[[NSBundle mainBundle] \
    pathForResource:@X ofType:@"tif"]]

imagesForLargeAnimation  = [[NSArray alloc] initWithObjects:
                    IMG("01"),
// (since we are allocing that image, of course we must release it eventually.)
                    IMG("02"),
                    IMG("03"),
                    ....
                    IMG("42"),
                    nil];

animationArea.animationImages = imagesForLargeAnimation;
//blah blah...

Later, once the animation has been stopped and is no longer being shown onscreen, to clean up the memory you'd have to do this:

-(void) cleanUpTheMemoryInTheBigAnimation
 {
 //blah blah..

 // for each of those big images in the array, release the memory:
 for (UIImage *uu in imagesForLargeAnimation)
    [uu release];

 // release the array itself
 [imagesForLargeAnimation release];
 imagesForLargeAnimation = nil;

Now, this all works perfectly and efficiently, it will not leak nor overuse memory if you repeatedly use different large animations.

The only problem is, of course you get the clang warning: "Potential leak of an object allocated on line 69", indeed you get scores of those warnings, one for each alloc.

What's the best idiom to avoid these warnings -- and make it safer and tighter?

Does anyone know?

For example, if you use autorelease, thus, in the code example above you'd use autorelease in the IMG define...

...in fact, when you release the NSArray (ie, [imagesForLargeAnimation release] ) ... at that point it will autorelease all the objects in the array? Is that correct? Or??

(Or should I be using some sort of newBlah function to put the images in, or .. ??)

If anyone knows the correct approach here to avoid the "potential leak", thanks!!!

{PS a reminder to basically never use imageNamed:, it's hopeless: it's only suitable for small UI-usage-type images. Never use imageNamed!}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

骑趴 2024-10-26 04:20:25

您不需要保留图像 - NSArray 会为您做到这一点。

试试这个:

#define IMG(X) [[[UIImage alloc] \
  initWithContentsOfFile:[[NSBundle mainBundle] \
    pathForResource:@X ofType:@"tif"]] autorelease]

你现在不需要这个代码:

// for each of those big images in the array, release the memory:
//for (UIImage *uu in imagesForLargeAnimation)
//    [uu release];

仅供参考(1):

如果你使用 imageNamed,你不会收到警告,因为 imageNamed 返回已经自动释放的对象,但 alloc/initWithcontentsOfFile 没有:)


仅供参考(2):

有NSArrays 上的一个方法,它对所有对象执行选择器:

[imagesForLargeAnimation makeObjectsPerformSelector:@selector(release)];

You don't need to keep the images retained - the NSArray will do that for you.

Try this :

#define IMG(X) [[[UIImage alloc] \
  initWithContentsOfFile:[[NSBundle mainBundle] \
    pathForResource:@X ofType:@"tif"]] autorelease]

and you don't now need this code :

// for each of those big images in the array, release the memory:
//for (UIImage *uu in imagesForLargeAnimation)
//    [uu release];

FYI (1) :

Were you to use imageNamed you would not get a warning because imageNamed returns already autoreleased objects but alloc/initWithcontentsOfFile does not :)


FYI (2) :

There is a method on NSArrays which performs a selector on all the objects :

[imagesForLargeAnimation makeObjectsPerformSelector:@selector(release)];
舟遥客 2024-10-26 04:20:25

将图像对象添加到数组后,您应该释放引用。但由于您使用宏来初始化它们,因此您没有对要添加到数组中的对象的引用。向宏添加 autorelease 将确保正确释放引用。另一种方法是使用循环来初始化对象,将它们添加到可变数组中,然后释放它们。

我的猜测是静态分析器看不到您正在手动释放数组中的所有对象。但是您应该在定义数组时注意它。

Once you add the image object to the array, you should release the reference. But since you are using a macro to initialize them, you don't have a reference to the object you are adding to the array. Adding an autorelease to the macro will make sure that reference is released properly. Another way to do it is to use a loop to initialize the objects, add them to a mutable array, then release them.

My guess is the static analyzer can't see that you are releasing all of the objects in the array manually. But you should take care of it at the time you are defining the array.

魄砕の薆 2024-10-26 04:20:25

您还可以使用imageNamed: 类方法。

imagesForLargeAnimation  = [[NSArray alloc] initWithObjects:[UIImage imageNamed:@"01"],
                                                            ..., 
                                                            [UIImage imageNamed:@"42"],
                                                            nil];

You can also use the imageNamed: class method.

imagesForLargeAnimation  = [[NSArray alloc] initWithObjects:[UIImage imageNamed:@"01"],
                                                            ..., 
                                                            [UIImage imageNamed:@"42"],
                                                            nil];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文