为什么NSSet objectEnumerator会增加保留计数?

时间:2008-12-01 17:11:08

标签: objective-c cocoa

在以下代码中获取objectEnumerator后,set1保留计数变为3.我很惊讶地看到,因为我没想到它会改变。我搜索了documentation,无法找到解释此效果的位置。

我认为额外的保留可能被Cocoa枚举逻辑设置为自动释放,并且在当前事件循环中实际上不会产生任何影响。有意义的是objectEnumerator逻辑需要对set1的引用,但我想知道它们是为什么被创建的。原因如下:如果我假设set1在代码发布后保留计数为零,那么我可以尝试重用另一个新集合。这不会导致问题,因为set1现在指向一个完全不同的对象/地址吗?

对于“奖励”积分,是否有一种枚举自动释放池的方法,看看它实际包含什么? TIA

#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>

#import <stdio.h>;

// macro to create an integer number:
#define INTOBJ(v) [NSNumber numberWithInt: v]

int main (int argc, char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    //Make set
    NSMutableSet *set1 = [[NSMutableSet alloc] initWithObjects:
        INTOBJ(1), INTOBJ(2), INTOBJ(5), INTOBJ(10), nil];

    printf("set1 #%lu\n", [set1 retainCount]);

    //Get enumerator of the set. This is where the retain count goes to 3:
    NSEnumerator *setEnum = [set1 objectEnumerator];
    printf("setEnum #%lu\n", [setEnum retainCount]);
    printf("set1 #%lu\n", [set1 retainCount]);

    //Iterate through the collection:
    printf("[");

    NSNumber *element;
    while ((element = [setEnum nextObject]) != nil)
        //do some this with item. printf is just for debugging:
        printf(" %i ", [element intValue]);

    printf("]\n");
    printf("set1 #%lu\n", [set1 retainCount]);

    [set1 release];
    printf("set1 after release #%lu\n", [set1 retainCount]);

    //More logic could go here reusing variable set1 since I assumed retain count = 0

    [pool release];

    return 0;
}

3 个答案:

答案 0 :(得分:4)

依赖于对象的保留计数通常不是一个好主意,因为它是框架的内部细节。而是确保您的代码遵守内存管理原则,特别是确保保留/新/复制和释放/自动释放是平衡的。

答案 1 :(得分:2)

据推测,枚举器保留了集合,因此在枚举期间不会取消分配。没有枚举的有效集合的枚举器将无法正常工作。实际上,枚举器确保它可行的唯一方法是保留它枚举的集合。

也就是说,除了之外,没有理由查看任何对象的保留计数来调试内存泄漏/双释放问题。只要遵循内存管理约定,就不必担心对象的保留计数。

答案 2 :(得分:1)

在发布后重用set1不会导致问题,因为保留计数在变量set1引用的Object上,而不在变量本身上。