Objective C内存泄漏问题

时间:2009-10-05 02:22:16

标签: iphone objective-c memory-leaks

Leaks仪器告诉我这个代码片段有漏洞。为什么会这样?

此代码片段位于viewDidLoad()

UINavigationItem *navItem=[self navigationItem];

UIBarButtonItem *addFeed = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addFeed)];
[navItem setRightBarButtonItem:addFeed]; // leaks says that 128 bytes leaked
[addFeed release];

UIBarButtonItem *reload = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh  target:self action:@selector(reload)];
[navItem setLeftBarButtonItem:reload]; // leaks says that 128 bytes leaked here too !
[reload release];
[navItem release];

6 个答案:

答案 0 :(得分:6)

你不应该发布navItem。你没有分配/保留/新建/创建它,所以你不发布它。

除此之外,您的代码看起来很好。这是方法中的一切吗?

答案 1 :(得分:3)

泄漏仪器只会告诉您泄漏内存的分配位置;它无法告诉你应该释放内存的位置但是因为没有可能的方法让它知道。你的泄漏正在其他地方发生。

此代码大部分都没有问题,但您不应该在最后发布navItem。您不是它的所有者,因为您没有在名称中使用名为allocnewcopy的方法创建它,因此您不应该发布它。

答案 2 :(得分:2)

如果您仍然收到泄漏消息并且无法追踪错误,您可以尝试使用最新最好的Xcode(版本3.2)中包含的静态分析器

构建>建立和分析

它将使用LLVM-Clang以非常方式静态分析您的代码。

http://developer.apple.com/mac/library/featuredarticles/StaticAnalysis/index.html

更新:

在您的代码段中:

UINavigationItem *navItem=[self navigationItem];

UIBarButtonItem *addFeed = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addFeed)];
[navItem setRightBarButtonItem:addFeed]; // leaks says that 128 bytes leaked
[addFeed release];

你的泄密可能来自设置新的rightBarButtonItem而不释放旧的。

这就是我的想法:

1)获取navigationItem的句柄(右侧栏按钮A)

2)创建一个新的UIBarButton项目(右侧栏按钮B)

3)setRightBarButtonItem为按钮B

现在按钮A在哪里?设置新按钮时应该由navItem释放。因此,当您第一次设置按钮时,您可能忘记释放按钮,或者您已将其保留在其他位置。

答案 3 :(得分:0)

你有NSZombieEnabled吗?这会导致NSZombie实例不保留对象,并且在运行Leaks工具时会看到“泄漏”。

答案 4 :(得分:0)

您似乎没有使用自定义viewDidLoad方法发布视图控制器。

答案 5 :(得分:0)

 [navItem setRightBarButtonItem:addFeed];

 [navItem setLeftBarButtonItem:reload];

您正在创建这些访问者中的对象的副本。这些访问器将retainCount递增1.您的访问器应释放每个对象,然后立即保留它们。

示例:

- (void) setTitle: (NSString*) newTitle {
    if (title != newTitle) {
        [title release];
        title = [newTitle retain]; // Or copy, depending on your needs.
    }

看看这里的技巧: Memory Management Programming

我相信这是什么了。所以仔细看看这两个访问者。