【问题标题】:Objective C memory leak issueObjective C 内存泄漏问题
【发布时间】:2009-10-05 02:22:15
【问题描述】:

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];

【问题讨论】:

    标签: iphone objective-c memory-leaks


    【解决方案1】:

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

    除此之外,您的代码看起来还不错。这就是方法中的所有内容吗?

    【讨论】:

      【解决方案2】:

      泄漏工具仅告诉您泄漏内存的分配位置;它无法告诉您应该在哪里释放内存,但没有告诉您,因为它不可能知道这一点。您的泄漏发生在其他地方。

      这段代码基本上没问题,除了你不应该在最后释放navItem。您不是它的所有者,因为您没有使用名称中名为 allocnewcopy 的方法创建它,因此您不应释放它。

      【讨论】:

        【解决方案3】:

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

        构建 > 构建和分析

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

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

        更新:

        在您的代码 sn-p 中:

        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 Item(制作右栏按钮B)

        3) setRightBarButtonItem 到按钮 B

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

        【讨论】:

        • 还有一些想法... rightBarButtonItem 是@property(nonatomic, retain) UIBarButtonItem *rightBarButtonItem,所以它应该在保留新的之前释放旧的。所以也许在你的代码中的其他地方你会保留旧按钮或在第一次设置后不释放它
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:
             [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

            我相信事情就是这样。所以仔细看看这两个访问器。

            【讨论】:

              猜你喜欢
              • 2011-07-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-02-04
              • 1970-01-01
              • 2011-06-07
              • 1970-01-01
              相关资源
              最近更新 更多