我的程序有内存泄漏

发布于 2024-12-14 11:26:09 字数 573 浏览 0 评论 0原文

-(IBAction)play2;

{
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =CFBundleCopyResourceURL(mainBundle, 
                                             (CFStringRef) @"Bear3", CFSTR ("wav"), NULL);

    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}

这给了我一个错误:

potential leak of an object allocated " CFBundleResourceURL
returns a Core Foundation object with a +1 retain count
-(IBAction)play2;

{
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =CFBundleCopyResourceURL(mainBundle, 
                                             (CFStringRef) @"Bear3", CFSTR ("wav"), NULL);

    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}

This is giving me an error:

potential leak of an object allocated " CFBundleResourceURL
returns a Core Foundation object with a +1 retain count

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

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

发布评论

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

评论(5

撑一把青伞 2024-12-21 11:26:09

AudioServicesCreateSystemSoundID (soundFileURLRef, &soundID); - 此处泄漏,因为创建添加了保留计数

使用 AudioServicesDisposeSystemSoundID 播放声音后

AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID); - leak here, because create added to retain count

use AudioServicesDisposeSystemSoundID after playing sound

酒几许 2024-12-21 11:26:09

CFBundleCopyResourceURL 包含副本,因此您对 soundFileURLRef 的保留计数实际上是 1。完成后,调用 CFRelease(soundFileURLRef) 来减少您的保留数数。

除了您收到的错误之外,SAKrisT 关于在使用 AudioServicesCreateSystemSoundID 创建的对象上调用 AudioServicesDisposeSystemSoundID 的答案也是需要解决的问题。

CFBundleCopyResourceURL contains copy so your retain count on soundFileURLRef is in fact 1. When you are done with it call CFRelease(soundFileURLRef) to decrement your retain count.

In addition to the error you're getting, SAKrisT's answer about calling AudioServicesDisposeSystemSoundID on the object you created with AudioServicesCreateSystemSoundID is also something to address.

烟织青萝梦 2024-12-21 11:26:09

CFBundleCopyResourceURL 创建一个 您拥有的 CFURLRef 对象,因此您需要在某个时刻使用 CFRelease。同样,您需要平衡对 AudioServicesCreateSystemSoundID 的调用与对 AudioServicesDisposeSystemSoundID 的另一个调用。

对于 Core Foundation,名称中包含 CreateCopy 一词的函数会返回您拥有的对象,因此在使用完该对象后,您必须放弃对该对象的所有权。有关 Core Foundation 内存管理的更多信息,请参阅 核心基础内存管理编程指南

只是为了给你一个提示,我可能会像这样处理内存管理(尽管我有一段时间没有编写 Objective-C 代码了)。这还假设您出于某种原因想要保留 URL 引用:

@interface MyClass
{
    CFURLRef soundFileURLRef;
    UInt32 soundID;
}

@end

@implementation MyClass

- (id) init
{
    self = [super init];
    if (!self) return nil;

    CFBundleRef mainBundle = CFBundleGetMainBundle();

    soundFileURLRef = CFBundleCopyResourceURL(mainBundle, CFSTR("Bear3"), CFSTR("wav"));

    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);

    return self;
}

- (void) dealloc
{
    AudioServicesDisposeSystemSoundID(soundID);
    CFRelease(soundFileURLRef);
    [super dealloc];
}

- (IBAction) play2
{
    AudioServicesPlaySystemSound(soundID);
}

CFBundleCopyResourceURL creates a CFURLRef object that you own, so you need to relinquish ownership of this object at some point with CFRelease. Similarly you will need to balance your call to AudioServicesCreateSystemSoundID with another call to AudioServicesDisposeSystemSoundID.

For Core Foundation, functions that have the word Create or Copy in their name return an object that you own, so you must relinquish ownership of it when you are done with it. For more information about Core Foundation memory management, see the Core Foundation Memory Management Programming Guide.

Just to give you a hint, I would probably handle the memory management like this (although I haven't coded Objective-C for a while). This also assumes you want to keep the URL reference for whatever reason:

@interface MyClass
{
    CFURLRef soundFileURLRef;
    UInt32 soundID;
}

@end

@implementation MyClass

- (id) init
{
    self = [super init];
    if (!self) return nil;

    CFBundleRef mainBundle = CFBundleGetMainBundle();

    soundFileURLRef = CFBundleCopyResourceURL(mainBundle, CFSTR("Bear3"), CFSTR("wav"));

    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);

    return self;
}

- (void) dealloc
{
    AudioServicesDisposeSystemSoundID(soundID);
    CFRelease(soundFileURLRef);
    [super dealloc];
}

- (IBAction) play2
{
    AudioServicesPlaySystemSound(soundID);
}
蓝眸 2024-12-21 11:26:09

如果您不使用 ARC(在 xcode 4.2 中可用),那么您需要释放您分配的任何内容。在[alert show] 之后添加[alert release]

If you're not using ARC (available in xcode 4.2) then you need to release anything you alloc. add [alert release] after [alert show].

桃扇骨 2024-12-21 11:26:09

每当您使用关键字“alloc”时,就意味着您正在为对象分配一些内存空间。现在,如果您不自己释放它或自动释放它,那么它会显示“内存泄漏”。它不仅涉及 uialertview,还涉及其他所有对象。
你可能想在dealloc()方法中释放alertview对象,但由于内存长时间未使用,仍然会出现内存泄漏。
所以,首先你通过[alert show]显示警报,然后你不再需要该对象,所以通过[alert release]释放它;
享受吧! :)

Whenever you use the keyword 'alloc' , it means you are allocating some memory space for your object. Now if you don't release it yourself or autorelease it, then it shows 'memory leak'. It is not only about uialertview, but for every other objects also.
You may want to release the alertview object in dealloc() method, but still it will show memory leak as the memory is unused for a long time.
So , first you show the alert by [alert show], then you need the object anymore, so release it by [alert release];
Enjoy !! :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文