MacOSX10.6,Cocoa项目,保留/发布gc
我有一个功能:
例如(为简洁而删除的错误处理)。
NSMutableArray * ListAllSubFoldersForFolderPath(NSString *folderPath)
{
NSMutableArray *a = [NSMutableArray arrayWithCapacity:100];
NSString *itemName = nil;
NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *e = [fm enumeratorAtPath:folderPath];
while (itemName = [e nextObject]) {
NSString *fullPath = [folderPath stringByAppendingPathComponent:itemName];
BOOL isDirectory;
if ([fm fileExistsAtPath:fullPath isDirectory:&isDirectory]) {
if (isDirectory is_eq YES) {
[a addObject: fullPath];
}
}
}
return a;
}调用函数每个会话只接收数组一次,将其保存下来供以后处理:
static NSMutableArray *gFolderPaths = nil;
...
gFolderPaths = ListAllSubFoldersForFolderPath(myPath);
[gFolderPaths retain];在这个阶段,一切看起来都很好。[gFolderPaths计数]返回找到的正确路径数,_gFolderPaths description_打印出所有正确的路径名。
问题:
当我稍后使用gFolderPaths时(例如,下一次运行事件循环),我的断言代码(以及Xcode中的gdb )告诉我它是零。
在第一次抓取之后,我不会以任何方式修改gFolderPaths,所以我假设我的内存管理已经结束,gFolderPaths正在由运行时发布。
我的假设/假定
在将每个字符串添加到可变数组中时,我不必保留它,因为这是自动完成的,但是一旦从函数中将数组交给我,我就必须保留它,因为我不会立即使用它。这是正确的吗?
任何帮助都是非常感谢的。
发布于 2010-06-16 10:12:59
对象不是“gonil”。
static NSMutableArray *gFolderPaths = nil;此声明声明gFolderPaths是一个保存指向NSMutableArray对象的指针的变量。您可以使用指向no:nil的指针初始化它。
这个初始化是有效的,并且是有意义的,因为您还没有一个数组放在这里--最好用nil指针进行初始化,而不是不初始化并且冒着一些随机指针在变量中的风险。(这在static变量中是不可能发生的,因为static变量被初始化为nil,但是显式性很好,并且显式初始化是无害的。)
--当我稍后使用
gFolderPaths时(例如,下一次通过事件循环运行)--我的断言代码(Xcode中的gdb )告诉我它是nil。
在第一次抓取之后,我不会以任何方式修改gFolderPaths,所以我假设我的内存管理已经结束,gFolderPaths正在由运行时发布。
不是的。运行时不释放对象。运行时是语言的一部分,retain和release是基础框架的一部分。这个框架就在语言的顶端。
因此,您可能猜到您或其他一些代码(例如,在框架中)释放了以前存储在gFolderPaths中的指针的对象。
不是的。如果发生了这种情况,gFolderPaths变量不会突然包含nil;它仍然包含指向同一对象的相同指针。如果这是对象死前的最后一个版本,那么gFolderPaths变量仍然包含指向同一对象的相同指针。
尝试记录指针(例如,使用NSLog(@"%p", gFolderPaths))将打印一个有效的地址,例如0x2381ab6780。尝试记录对象(例如,使用%@)几乎肯定会崩溃,因为对象已经死了。
事情不是这样的。您说您的断言和调试器命令显示gFolderPaths变量包含nil。
有两种明显的可能性:
nil,就是没有分配任何东西。您说您正在记录您分配给变量的指针的数组,并且说明是正确的,所以我们可以完全排除这种可能性。(记录计数将不是那么可靠的测试,因为[nil count]将成功返回0.)这导致了第三种可能性:
gFolderPaths variables.我猜您有两个函数或方法(或每个函数或方法中的一个),它们都包含以下一行:
static NSMutableArray *gFolderPaths = nil;那不管用。这两个gFolderPaths变量都是静态的,但也是声明它们的函数/方法的本地变量。每个函数/方法都有自己的gFolderPaths变量,因此您有两个这样的变量,彼此分离。
您需要在任何函数或方法之外将gFolderPaths声明为静态全局变量。更好的是,如果只从实例中访问它,则将其作为实例变量。无论哪种方式,如果要在两个函数或方法之间共享局部变量,则它不能是局部变量。
如果您有两个这样的全局声明,但每个声明位于不同的文件中,则可能发生另一种情况。在文件作用域中声明的变量的static意味着“仅在此文件中可见”,因此这会导致同样的问题:当您打算拥有一个共享变量时,两个单独的变量。如果这是您的问题,立即修复是从它们中删除static关键字,但是如果要以这种方式使用全局变量,则应该重新考虑您的设计。
https://stackoverflow.com/questions/3051426
复制相似问题