自动释放池外的 NSString alloc 会造成神秘的内存泄漏?

Posted

技术标签:

【中文标题】自动释放池外的 NSString alloc 会造成神秘的内存泄漏?【英文标题】:NSString alloc outside autorelease pool creates mysterious memory leak? 【发布时间】:2011-09-11 01:39:59 【问题描述】:

在运行时手动分配和释放内存时产生如下错误:

objc[10430]: Object 0x109014b60 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

我搜索了互联网,但通常这些错误是由于未释放内存或使用自动释放的速记引起的...我找不到任何未释放的内存,也没有使用自动释放的速记...希望您能提供帮助!

我的代码是:

#import "try.h"

@implementation try

- (try*)initWithSwing

    self = [super init];
    if (self) 
        [self tellAboutSwing:YES];
    

    return self;


- (void) tellAboutSwing: (BOOL) swing 

    NSString *s = [[NSString alloc] initWithFormat: @"%@ %@", @"Do we have a swing on our playground?", (swing ? @"Yes" : @"No")];


    // cast to a char
    const char *c = [s UTF8String];
    [s release];    
    printf("%s", c);



- (void) dealloc 
    printf( "Deallocing Playground\n" );
    [super dealloc];


int main(void) 
    try *t;
    t = [[try alloc] initWithSwing];
    [t release];


@end

在实例方法中放置一个自动释放池可以解决这个问题,但对于NSString alloc 来说,这不是必需的。虽然我是 Objective-C 的新手,但我想我已经掌握了拥有和释放变量的概念,但是我很难在这里找到我的错误。

这是我的 .h 文件:

#include <Foundation/Foundation.h>


@interface try : NSObject
- (void) tellAboutSwing: (BOOL) swing;
@end

非常感谢您的帮助:)

问候,

罗伯特

【问题讨论】:

仅仅因为 you 不使用 autorelease 并不意味着 frameworks 不使用。 NSString 类可以在任何时候自动释放它想要的任何东西(只要它拥有它)。这就是为什么在使用 Objective-c 时总是应该有一个自动释放池的原因。 我没有发现这种情况。我当然收到过上述信息,但这始终是由于一个明显的原因。在这种情况下,UTF8String 调用可能是罪魁祸首。 【参考方案1】:

IIRC -[NSString UTF8String] 使用自动释放的 NSData 来实际保存 UTF-8 C 字符串的字节。

更新:这是一种仅使用 C 函数的更简单方法:

- (void) tellAboutSwing: (BOOL) swing     
    printf("%s %s", "Do we have a swing on our playground?", (swing ? "Yes" : "No"));

【讨论】:

感谢您的帮助!就是这样!现在只是学习部分(我可能从一开始就使用UTF8String 来避免自动释放);我怎样才能避免创建自动释放的NSData 对象,同时仍将NSString 转换为char?我可以取得 NSData 对象的所有权吗? [c retain] 导致编译器错误,为什么?就像我说的,我是 Objective-C 的新手,我正在努力获得一个扎实的理解,关于 MM 的大多数文档都没有涉及这些细节。在此先感谢罗伯特! 有什么理由不能只使用自动释放池吗?也就是说,您可以改用老式的 C 函数。【参考方案2】:

您应该只使用 NSAutoreleasePool。有一个是正常的,但在某些时候你会找不到一个不在内部创建自动释放对象的替代方案。

我认为你应该查看一些关于内存管理和基础知识的教程和指南,否则你将很难理解 Objective-C。

例如,iTunesU 上有一个很棒的免费课程,它解释了 Objective-C 的基础知识。

【讨论】:

以上是关于自动释放池外的 NSString alloc 会造成神秘的内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

文字 NSString 是自动释放还是需要释放?

NSString - stringWithFormat 自动释放

Redis中RedisModule_Alloc()的自动内存管理

NSString componentsSeparatedByString: 返回自动释放的数组吗?

从 NSArray objectAtIndex 返回的 NSString 是自动释放还是保留

Objective-C 对象的分配/释放