Cocoa内存管理-对象在我身上为零
Mac OS X 10.6,Cocoa项目,带有保留/发布gc 我有一个函数:Cocoa内存管理-对象在我身上为零,cocoa,memory-management,Cocoa,Memory Management,Mac OS X 10.6,Cocoa项目,带有保留/发布gc 我有一个函数: 迭代特定目录,扫描其中的子文件夹(包括嵌套的子文件夹),构建一个NSMutableString数组(每个找到的子文件夹路径一个字符串),然后返回该数组 e、 g.(为简洁起见,删除了错误处理) 调用函数在每个会话中仅获取一次阵列,并将其保留以供以后处理: static NSMutableArray *gFolderPaths = nil; ... gFolderPaths = ListAllSubFolder
- 迭代特定目录,扫描其中的子文件夹(包括嵌套的子文件夹),构建一个NSMutableString数组(每个找到的子文件夹路径一个字符串),然后返回该数组
static NSMutableArray *gFolderPaths = nil;
...
gFolderPaths = ListAllSubFoldersForFolderPath(myPath);
[gFolderPaths retain];
在这个阶段,一切似乎都很好。[gFolderPaths count]返回找到的正确路径数,[gFolderPaths description]打印出所有正确的路径名
问题:
当我稍后使用gFolderPaths时(比如,下一次运行我的事件循环),我的断言代码(以及Xcode中的gdb)告诉我它是nil
在初始抓取之后,我没有以任何方式修改gFolderPaths,因此我认为我的内存管理已经失败,运行时正在释放gFolderPaths
我的假设/假设
在我将字符串添加到可变数组时,我不必保留每个字符串,因为这是自动完成的,但一旦数组从函数中移交给我,我就必须保留它,因为我不会立即使用它。这是正确的吗
非常感谢您的帮助。对象不会“去
nil
”
static NSMutableArray *gFolderPaths = nil;
此声明声明gFolderPaths
是一个变量,它包含指向NSMutableArray对象的指针。
您可以使用指向无对象的指针初始化它:nil
这个初始化是有效的,并且有意义,因为您没有数组放在这里,但是使用nil
指针初始化要比不初始化好得多,因为变量中存在一些随机指针。(这不能发生在静态
变量上,因为静态
变量被初始化为nil
,但显式性很好,显式初始化是无害的。)
当我稍后使用gFolderPaths
时(比如,下一次运行我的事件循环),我的断言代码(以及Xcode中的gdb)告诉我它是nil
在那次初始抓取之后,我没有以任何方式修改gFolderPaths
,因此我认为我的内存管理已经完成,运行时正在释放gFolderPaths
否。运行时不释放对象。运行时是语言的一部分,<>代码>留存和<代码>发布<代码>是基础框架的一部分。该框架位于该语言之上
因此,您可能会猜测您或其他一些代码(例如,在框架中)释放了对象,您以前将其指针存储在gFolderPaths
中
否。如果发生这种情况,gFolderPaths
变量不会突然包含nil
;它仍将包含指向同一对象的同一指针。如果这是对象死亡之前的最后一个版本,则gFolderPaths
变量仍将包含指向同一个现已死亡的对象的相同指针
尝试记录指针(例如,使用NSLog(@“%p”,gFolderPaths)
)将打印一个看起来有效的地址,例如0x2381ab6780
。尝试记录对象(例如,使用%@
)几乎肯定会崩溃,因为对象已死亡
事实并非如此。您说过您的断言和对调试器的命令显示gFolderPaths
变量包含nil
有两种明显的可能性:
nil
,要么您从未指定任何内容。你说你正在记录一个数组,这个数组的指针被分配给了变量,并且描述被验证了,所以我们可以完全排除这种可能性。(记录计数在测试中并不可靠,因为[nil count]
将成功返回0。)gfolderpath
变量。
我猜您有两个函数或方法(或每个函数或方法中的一个)都包含这一行:
static NSMutableArray *gFolderPaths = nil;
那不行。两个gFolderPaths
变量都是静态的,但也是您在其中声明它们的函数/方法的局部变量。每个函数/方法都有自己的gFolderPaths
变量,因此有两个这样的变量,彼此独立
您需要在任何函数或方法之外,将gFolderPaths
声明为静态全局变量。更好的是,如果只从实例访问它,则将其设置为实例变量。无论哪种方式,如果要在两个函数或方法之间共享它,它都不能是局部变量
另一种可能发生这种情况的方式是,如果您有两个这样的全局声明,但每个声明位于不同的文件中<在文件范围内声明的变量上的code>static表示“仅在此文件中可见”,因此这会导致相同的问题:当您想要有一个共享变量时,会出现两个单独的变量。如果这是您的问题,立即解决的办法是从这两个变量中删除
static
关键字,但是如果您打算以这种方式使用全局变量,您应该重新考虑您的设计。…这只是全局变量不好的一个原因。非常感谢Peter。你的回答很准确#3:我实际上已经声明了两个“gFolderPaths”,因为我会复制粘贴作业。e、 g.“NSMutableArray*GFolderPath=”中。哎哟已经做了20多年了,但我仍然被基本的东西咬着了。@亚历克斯,我很少用globals。我把它们和's'一起使用
static NSMutableArray *gFolderPaths = nil;