0

我正在使用一个简单的函数通过标签向用户显示消息。功能如下:

-(void) showMessage:(NSString*) message
{  
    Message.text = message;
    [message release]; 
}

如果我从主线程调用此函数,则没有内存泄漏。但是,如果我从单独的线程调用此函数,则仪器监视器会在调用该函数后立即显示 16 字节的内存泄漏。如果我注释掉函数调用,则看不到泄漏。有谁知道为什么?我正在使用 iPhone SDK 3.0。仪器监视器没有指向我的任何功能来指示泄漏。它只显示了 UILabel 中的一两个函数。

4

2 回答 2

5

查看那里的代码,您似乎在某个地方的内存管理错误-您永远不 release应该将对象作为方法参数接收。考虑以下:

-(void)doSomething {

    NSString *aStr = [[NSString alloc] init];

    [self showMessage:aStr];

    NSString *anotherStr = [aStr stringByAppendingString:@"Hi"];
    // ^^ This call will crash as aStr has been released and is invalid.
}

-(void) showMessage:(NSString*) message {
    Message.text = message; 
    [message release];
}

...在上面的示例中使用您的方法会导致崩溃,因为 showMessage: 方法会释放传递的字符串。

我知道这并不能直接回答您的问题,但是正确进行内存管理,您的问题很可能会消失。我建议您阅读 Apple 的Cocoa 内存管理编程指南

编辑:另外,UIKit 不是线程安全的——你不应该从除了主线程之外的任何地方调用 UIKit 对象的消息。请参阅performSelectorOnMainThread:withObject:从另一个线程调用主线程上的消息。

于 2009-11-23T10:51:49.167 回答
0

很难从这段代码中弄清楚。此外,仪器不是一个完美的机制,当然不能用于发现(和解决)这种大小的泄漏。

它甚至可能不是泄漏,但这取决于您在函数调用之前和之后如何初始化和释放消息字符串。

如果你像这样初始化它;

NSString *message = [[NSString alloc] initWithString:@"hello"];

消息将收到 +1 的保留计数,您必须在将其作为参数传递给函数后释放它。在函数内部,它将再次被标签保留。如果您使用自动释放消息对其进行初始化,那么情况就完全不同了。

此外,当您使用 NSThread 时,请在您的方法中使用 NSAutoreleasePool。

我还建议运行 XCode 的静态分析器,它可以帮助您发现不正确的内存管理。

于 2009-11-23T11:01:26.007 回答