【问题标题】:iphone: Memory Leak involving NSStringiphone:涉及 NSString 的内存泄漏
【发布时间】:2012-02-17 10:13:44
【问题描述】:

如果用户对其照片库进行更改,我这里有一小段代码会更新ALAssetGroup(相册):

- (void) ALAssetsLibraryChangedNotification
{
    [[self activityIndicator] startAnimating]; 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [[self library] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
    {
        if (group != nil)
        {
            NSString *newAlbumID = [[NSString alloc] initWithString: [group valueForProperty: ALAssetsGroupPropertyPersistentID]]; 

            if ([newAlbumID isEqualToString: self.albumID])
            {
                self.album = group;
                [self loadPhotos];
                [newAlbumID release];
                return;
            }

            [newAlbumID release];
        }

    }
    failureBlock:^(NSError *error) 
    {
    }];

    [pool release];

}

它有效,但只是在我得到“signalbrt”和相应的“-[UIButtonContent isEqualToString:]: unrecognized selector sent to instance”之前很长时间(有时UIButtonContent 将改为NSArray)。我还启用了僵尸并收到类似“*** -[CFString release]: message sent to deallocated instance" and "*** -[CFString class]: message sent to deallocated instance”的消息。我尝试过以多种不同的方式分配字符串,但没有一种可以正常工作。有谁知道这里发生了什么?

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch memory-leaks


    【解决方案1】:

    试试

            NSString *newAlbumID = [[NSString alloc] initWithString: [group valueForProperty: ALAssetsGroupPropertyPersistentID] autorelease]; 
    

    并删除此对象的其他版本。

    【讨论】:

      【解决方案2】:

      我的第一个猜测是怀疑self.albumIDself.album 被声明为assign 而不是retaincopy,或者loadPhotos 有问题。检查这些属性的声明并暂时删除loadPhotos 调用。它仍然崩溃吗?

      您分配的字符串的两个版本都符合犹太教规,但代码的组织方式使其难以推理。你应该重构它,这样字符串要么自动释放,要么释放一次。

      【讨论】:

        【解决方案3】:

        我认为问题很可能与“组”变量或对该组变量的“valueForProperty”调用有关。这可能会在您下方某处释放。因此,当您从“组”变量的属性初始化“newAlbumId”时,您将获得一个指向随机内存的指针(因为组对象或已被释放),最终成为指向“UIButtonContent”的指针或者有时和'NSArray'。因此,执行“isEqualToString”会得到抛出的错误。同样,这就是您在启用僵尸时收到警告的原因。

        当您启用 NSZombies 时,您是否会收到与访问组变量有关的任何警告?

        此外,组变量内存引用的对象是如何管理的 - 您是否分配/初始化并将其直接分配给包含对象中的 iVar(而不是通过属性访问器作为属性)?如果是这样,请确保您在此分配之后没有“释放”它,因为它不是一个属性,它不会保留在 iVar 分配中 - 您只需在您的 dealloc 方法中释放它(或将其设置为属性)。

        仅查看 ALAssetsGroup 类,您很可能通过分配便捷方法调用的结果来初始化组 iVar - 如果是这样,此便捷方法会自动释放它返回的组对象,因此您需要确保“保留”将其分配给包含对象中的组变量时的值。 (或者可能更简单,在您的包含对象上设置一个保留属性,并通过属性访问器方法进行分配)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-30
          • 2011-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-05
          相关资源
          最近更新 更多