2011-11-08 104 views
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 

回答

2

CFBundleCopyResourceURL后保留数量

使用AudioServicesDisposeSystemSoundID包含副本,以便您的soundFileURLRef保留计数其实1.当你用它做打电话CFRelease(soundFileURLRef)递减您的保留计数。

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

+0

避免讨论对象的实际保留计数(严格来说是实现细节),而是根据所有权来考虑对象。 – dreamlax

+0

@dreamlax我正在讨论保留计数,因为在错误中提到了问题的关键。 – NJones

+0

更仔细地阅读错误,它不告诉你*实际*保留计数,只是*相对*保留计数的所有权。 – dreamlax

2

CFBundleCopyResourceURL创建CFURLRef对象您拥有,所以你需要放弃这个对象的所有权在某点CFRelease。同样,您需要将您的电话与AudioServicesCreateSystemSoundID之间的通话另外拨打AudioServicesDisposeSystemSoundID

为核心基础,这个字在他们的名字CreateCopy返回你拥有一个对象的功能,所以你必须放弃它的所有权,当你用它做。有关Core Foundation内存管理的更多信息,请参见Core Foundation Memory Management Programming Guide。为了给你一个提示,我可能会像这样处理内存管理(尽管我还没有编码Objective-C一段时间)。这还假定您想保留无论什么原因,参考网址:如果你不使用ARC(在Xcode 4.2可用),那么你需要释放任何你的alloc

@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); 
} 
+0

当我释放后,声音将不再播放 – alfred

+1

当你不再需要它时释放它*,即当你的类正在释放。 – dreamlax

+0

什么是释放它的代码 – alfred

1

。在[alert show]之后加[alert release]

+0

http://meta.stackexchange.com/questions/111928/why-were-these-questions-merged – chown

-1

无论何时使用关键字'alloc',这意味着你正在为你的对象分配一些内存空间。现在,如果您不自己释放它或自动释放它,那么它会显示“内存泄漏”。它不仅是关于uialertview,而且还包括其他所有对象。
您可能想要在dealloc()方法中释放alertview对象,但仍会显示内存泄漏,因为很长一段时间内存未使用。
因此,首先您通过[alert show]显示警报,然后您需要该对象,因此通过[alert release]释放它;
享受! :)

+2

-1:他可以'因为作用域在pushAbout函数内部,所以在dealloc中释放。这并不是说它会显示内存泄漏 - 这是内存泄漏 - 如果长时间未使用但最终会释放,它不会显示为泄漏。重新阅读内存管理指南。 – jrtc27

+0

http://meta.stackexchange.com/questions/111928/why-were-these-questions-merged – chown