2008-12-01 33 views
1

在下面的代碼中獲得objectEnumerator後,set1的保留計數變爲3.我很驚訝地發現,因爲我沒有想到它會改變。我搜索了documentation,但無法找到解釋此效果的位置。爲什麼NSSet objectEnumerator遞增保留計數?

我認爲額外的保留可能是通過Cocoa枚舉邏輯設置爲autorelease,並且在當前事件循環中不會有任何效果。這是有道理的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; 
} 

回答

4

依賴對象的保留計數通常不是一個好主意,因爲它是框架的內部細節。相反,請確保您的代碼符合內存管理原則,特別是確保保留/新建/複製和釋放/自動釋放均衡。

+0

我是未經洗刷的.NET開發人員之一進入Obj-C,所以我錯過了管理GC。感謝像你這樣的人,我正在處理保留計數的問題。在.NET中,變量在超出範圍時被「釋放」,並且未被引用。你對這篇文章有什麼看法:http://www.kickingbear.com/blog/?p=17 – 2008-12-01 20:22:19

1

重用SET1不會造成問題,因爲保留計數是由變量設置1所引用的對象,而不是變量本身。

2

推測,枚舉器保留集合,以便在枚舉過程中不會取消分配。沒有有效集合枚舉的枚舉器將無法很好地工作。事實上,統計員確定其工作的唯一方法是保留它列舉的收集。

這就是說,有實在沒有理由永遠看任何物體的保留計數除了用於調試內存泄漏/雙釋放問題。只要你遵循內存管理約定,你永遠不需要擔心對象的保留計數。