【问题标题】:Why does NSSet objectEnumerator increment the retain count?为什么 NSSet objectEnumerator 会增加保留计数?
【发布时间】:2008-12-01 17:11:08
【问题描述】:

在下面的代码中得到 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;
}

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

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

    【讨论】:

    • 我是进入 Obj-C 的未洗过的 .NET 开发人员之一,所以我想念托管 GC。感谢像你这样的人,我掌握了处理保留计数的窍门。在 .NET 中,变量在超出范围并且不被引用时被“释放”。你觉得这篇文章怎么样:kickingbear.com/blog/?p=17
    • 我能理解你为什么定义了这些宏,但它们会让我在代码审查中感到困惑 ;-)
    【解决方案2】:

    大概是枚举器保留了集合,这样它就不会在枚举过程中被释放。没有要枚举的有效集合的枚举器不会很好地工作。事实上,确保枚举器能够正常工作的唯一方法是保留它所枚举的集合。

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

    【讨论】:

      【解决方案3】:

      释放后重用set1不会有问题,因为retain count是在变量set1引用的Object上,而不是在变量本身上。

      【讨论】:

        猜你喜欢
        • 2011-11-10
        • 2011-08-24
        • 2014-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多