Objective c 泄漏工具不存在';t报告os x上的内存泄漏

Objective c 泄漏工具不存在';t报告os x上的内存泄漏,objective-c,macos,memory-leaks,Objective C,Macos,Memory Leaks,我正在尝试从命令行学习如何使用泄漏工具,下面是我的代码,它应该会在NSString上产生泄漏: #import <Foundation/Foundation.h> #import <unistd.h> int main(int argc, const char *argv[]) { NSString *string = [[NSString alloc] init]; pid_t pid = getpid(); NSLog(@"pid: %d"

我正在尝试从命令行学习如何使用泄漏工具,下面是我的代码,它应该会在
NSString
上产生泄漏:

#import <Foundation/Foundation.h>
#import <unistd.h>

int main(int argc, const char *argv[])
{
    NSString *string = [[NSString alloc] init];

    pid_t pid = getpid();
    NSLog(@"pid: %d", pid);

    string = nil;
    [NSThread sleepForTimeInterval:20];

    return 0;
}
#导入
#进口
int main(int argc,const char*argv[]
{
NSString*string=[[NSString alloc]init];
pid_t pid=getpid();
NSLog(@“pid:%d”,pid);
字符串=零;
[NSThread sleepForTimeInterval:20];
返回0;
}
我了解到泄漏每10秒刷新一次(不确定这是否属实,但我将间隔设置为20秒)

这应该会产生泄漏,因为它不在自动释放池中,而且我使用
-fno objc arc
编译它是为了“安全”

我多次尝试运行泄漏
[pid]
,但未报告泄漏。我做错了什么? 另外,我是一个命令行迷,我真的希望能够使用类似valgrind的东西,它不太支持OSX10.8。为了使用leaks工具,我不得不在代码中加入睡眠,这很烦人

有人能在这里照几盏灯吗

NSString *string = [[NSString alloc] init];
返回空字符串的共享实例(多个调用返回同一实例)。 基础框架保持对该共享实例的引用,因此 没有内存泄漏

对于其他不可变类(
NSArray
NSDictionary
)也可以观察到同样的行为

如果你把你的线路换成

NSMutableString *string = [[NSMutableString alloc] init];
然后您将看到内存泄漏

返回空字符串的共享实例(多个调用返回同一实例)。 基础框架保持对该共享实例的引用,因此 没有内存泄漏

对于其他不可变类(
NSArray
NSDictionary
)也可以观察到同样的行为

如果你把你的线路换成

NSMutableString *string = [[NSMutableString alloc] init];
然后您将看到内存泄漏

  • 如果使用ARC,则不会出现泄漏
  • 空字符串(
    [[NSString alloc]init]
    )绝对是一个共享/重用的实例。系统必须保留对共享实例的引用,因此泄漏不会(正确地)报告它
  • 更好的测试是使用自定义对象。然后你就可以确定这里面没有魔法了

    #if __has_feature(objc_arc)
    #error This leaks test only works when ARC is off
    #endif
    
    @interface Orphan : NSObject @end
    @implementation Orphan @end
    
    
    // in main, create an object without keeping a reference to it:
    [Orphan new];
    
  • 如果使用ARC,则不会出现泄漏
  • 空字符串(
    [[NSString alloc]init]
    )绝对是一个共享/重用的实例。系统必须保留对共享实例的引用,因此泄漏不会(正确地)报告它
  • 更好的测试是使用自定义对象。然后你就可以确定这里面没有魔法了

    #if __has_feature(objc_arc)
    #error This leaks test only works when ARC is off
    #endif
    
    @interface Orphan : NSObject @end
    @implementation Orphan @end
    
    
    // in main, create an object without keeping a reference to it:
    [Orphan new];
    

    我不该忘了弦池。你的解决方案有效。然而,如果我在程序退出之前去掉'string=nil',它就不起作用了(这是有意义的,因为string仍然拥有所有权)。但在实践中,我不可能为所有要监视的对象设置nil。有更好的解决办法吗?我不应该忘记字符串池。你的解决方案有效。然而,如果我在程序退出之前去掉'string=nil',它就不起作用了(这是有意义的,因为string仍然拥有所有权)。但在实践中,我不可能为所有要监视的对象设置nil。有更好的解决办法吗?我不应该忘记字符串池。你的解决方案有效。然而,如果我在程序退出之前去掉'string=nil',它就不起作用了(这是有意义的,因为string仍然拥有所有权)。但在实践中,我不可能为所有要监视的对象设置nil。有更好的解决方案吗?@bohanl没有,在使用
    泄漏
    工具时没有。您可以在ARC中使用
    \uuu弱
    引用,但这在实践中不起作用,因为引用很弱。@bohanl不过有更好的工具来调试这种问题。您正在搜索所谓的“废弃内存”(内存仍然存在指针,但对象仍然不再需要)。工具包含可用于执行“堆快照分析”(现在称为生成分析)的“分配”工具。这是一个寻找被抛弃记忆的绝妙工具。我不应该忘记字符串池。你的解决方案有效。然而,如果我在程序退出之前去掉'string=nil',它就不起作用了(这是有意义的,因为string仍然拥有所有权)。但在实践中,我不可能为所有要监视的对象设置nil。有更好的解决方案吗?@bohanl没有,在使用
    泄漏
    工具时没有。您可以在ARC中使用
    \uuu弱
    引用,但这在实践中不起作用,因为引用很弱。@bohanl不过有更好的工具来调试这种问题。您正在搜索所谓的“废弃内存”(内存仍然存在指针,但对象仍然不再需要)。工具包含可用于执行“堆快照分析”(现在称为生成分析)的“分配”工具。这是一个寻找被遗弃记忆的绝妙工具。