Iphone NSArray内存管理

Iphone NSArray内存管理,iphone,Iphone,由于某种原因,当我释放NSArray时,我得到了EXC_BAD_访问异常。以下是实施方案: -(void) loadAllAlphabets { NSBundle *bundle = [NSBundle mainBundle]; NSArray *imagesPath = [[NSArray alloc] init]; imagesPath = [bundle pathsForResourcesOfType:@"png" inDirectory:@"Images"]

由于某种原因,当我释放NSArray时,我得到了EXC_BAD_访问异常。以下是实施方案:

-(void) loadAllAlphabets
{
    NSBundle *bundle = [NSBundle mainBundle]; 
    NSArray *imagesPath = [[NSArray alloc] init]; 

    imagesPath = [bundle pathsForResourcesOfType:@"png" inDirectory:@"Images"];

    alphabets = [[NSMutableArray alloc] init]; 

    NSString *fileName = [[NSString alloc] init]; 

    for(int i=0; i<= imagesPath.count -1 ; i++) 
    {
        fileName = [[imagesPath objectAtIndex:i] lastPathComponent];
        CCSprite *sprite = [CCSprite spriteWithFile:fileName];

        sprite.userData = [[fileName stringByDeletingPathExtension] uppercaseString];   

        [alphabets addObject:sprite]; 
    }

    // release fileName 
    [fileName release]; 
    fileName = nil; 

    [imagesPath release]; // this causes the application to crash with EXC_BAD_ACCESS
//  imagesPath = nil; 
更新2:

另一个与本帖相关的问题。在下面的代码中,我手动初始化了一个新的NSMutableArray

alphabets = [[NSMutableArray alloc] init]; 

稍后,我将CCSprite(Cocos2d对象)插入字母表数组。CCSprite是自动释放对象。我还需要手动释放字母表吗?因为,在一段时间后,所有对象都被释放,内存将被返回,但字母表NSMutable数组中还剩下什么呢

内存管理中的一般经验法则-只有当您使用包含new、copy或alloc的方法获取对象时,才应释放该对象(标准方法遵循该规则,您也应遵守该规则)

在您的情况下,您可以使用
pathsforesourcesoftype:
方法获取imagesPath对象,该方法返回一个自动释放的对象,因此您不能自己释放它

编辑:是的,您需要在某处释放
字母表
对象(出于同样的原因-您使用alloc方法获得它)


Objective-c容器拥有添加到容器中的对象的所有权,当对象添加到数组中时,它们会被保留,因此可以保证它们的生命周期至少与容器的生命周期一样长。当您从集合中删除对象或集合本身被销毁时,其成员将被释放(以补偿添加时保留)。

我认为混淆之处在于:

NSArray *imagesPath = [[NSArray alloc] init]; 
imagesPath = [bundle pathsForResourcesOfType:@"png" inDirectory:@"Images"];
第一行创建一个新对象。这个对象确实需要释放

第二行使用新的自管理对象覆盖该对象。这不需要手动释放

这意味着你泄露了第一张照片


通常,如果
alloc
复制对象,则需要释放该对象。在释放(或自动释放)对象内容之前,不应过度写入对象。

还可以在初始化时泄漏内存,并使用空的不可变数组初始化
imagesPath
,然后在将
pathForerSources:
的结果分配给对象时丢弃它。只需这样做:

NSArray *imagesPath = [bundle pathsForResourcesOfType:@"png" inDirectory:@"Images"];
文件名
相同的错误。不需要使用空的不可变字符串初始化它


也不要释放
fileName
,因为它也是一个自动释放的对象。

谢谢Vladimir!因此,即使我分配了imagesPath,Paths ForResourceSoftype仍返回了一个autorelease对象,我不能手动释放该对象。当您将imagesPath重新分配给Paths ForResourceSoftype:调用时,会发生泄漏,因为您已经分配了文件名,而文件名是autorelease对象的原因是因为它来自imagesPath NSArray,对吗?另外,如果我正在运行一个循环并分配文件名,这意味着我正在为每个循环计数创建NSString的新对象。@azamsharp是的,行“fileName=[[NSString alloc]init];”中的值在循环内为其指定自动释放的字符串时,将丢弃该字符串。就我个人而言,我会在循环之前用nil初始化fileName是的,你在每次循环迭代中都会创建一个string对象,但是这些字符串是自动删除的,所以运行时会自己处理它们——你不必担心它们,我只是在循环外创建了一个NSString*fileName=nil。
NSArray *imagesPath = [bundle pathsForResourcesOfType:@"png" inDirectory:@"Images"];