2010-07-26 72 views
0

爲什麼計數器變量等於3而不是2?爲什麼保留數大於我的預期(使用addSubview)

@interface ScoreView : UIImageView 
... 


- (id)initWithFrame:(CGRect)frame 
{ 
    if (!(self = [super initWithFrame:frame])) 
     return self; 

    _scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, 10, 10)]; 
    [self addSubview:_scoreLabel]; 

    int counter = [[[self subviews] objectAtIndex:0] retainCount]; // WHY 3? 
    return self; 
} 
+1

你看了上retainCount的文檔? 」 ...「 – user123444555621 2010-07-26 06:46:40

+0

我已經閱讀了」初學者「的文檔,它說保留計數器增加,當」alloc/copy/new「發生時,並且減少,當發佈時調用。 如果你有具體的文檔 - 請與我分享一個鏈接到它 – 2010-07-26 07:03:02

回答

3

-retainCount is not reliable

重要:此方法在調試內存管理問題時通常沒有任何價值。因爲任何數量的框架對象都可能保留了一個對象以保存對它的引用,同時autorelease池可能在對象上保存了任意數量的延遲發佈,所以很難從此獲得有用的信息方法。

在你的情況,具體的原因是因爲-subview也導致所有子視圖要保留一次,由複製.layer.sublayers值到一個新的數組*:

UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; 
NSLog(@"%d", [label retainCount]); // 1 
[someView addSubview:label]; 
NSLog(@"%d", [label retainCount]); // 2 
[someView subviews]; 
NSLog(@"%d", [label retainCount]); // 3 

有沒有必要擔心它,因爲數組是autoreleased,並且retainCount將在以後回落到2。您所需要的只是確保當前功能導致的淨保留計數與所有權狀態一致。


*:中.subviews具體實現是:

-(NSArray*)subviews { 
      // irrelevant ... snipped 

     NSArray* sublayers = [_layer.sublayers copy]; 
     int count = [sublayers count]; 

      // irrelevant ... snipped 

      res = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); 
      for (int i = 0; i < count; ++ i) { 
       UIView* view = _UIView([sublayers objectAtIndex:i]); 
       if (view) 
        CFArrayAppendValue(res, view); 
        // ^-- this causes an extra -retain to each subview. 
      } 

      // irrelevant ... snipped 
} 
+0

哇,是那裏的逆工程蘋果版權代碼? – JBRWilkinson 2010-07-26 08:27:26

1

就發送MESSAGE-

_scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, 10, 10)];//here 
    [self addSubview:_scoreLabel]; 

    int counter = [[[self subviews] objectAtIndex:0] retainCount]; //here 

立即檢查並讓我們知道了進一步的問題肯定結束括號「]」。

+0

對不起,發佈不正確的版本的代碼 我編輯了第一條消息,正確的一個 而我仍然有櫃檯等於3,而不是2 – 2010-07-26 06:41:20

0

我認爲你不知道保留機制。

這很簡單。

初始值[init]和[copy]方法應增加retainCount。 ==> retainCount == 1 主叫[addSubview]後,自具有_scoreLabel,然後retainCount + 1 ==> retainCount ==新保留2

所以,U得到了retainCount(2)

ù應該用下面的代碼來改變你的代碼。

_scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,10,10); === _scoreLabel = [[[[UILabel alloc] initWithFrame:CGRectMake(0,0,10,10)] autorelease];};}};

或顯示呼叫釋放這樣

==> [_scoreLabel釋放];

[autorelease]方法會在事件驅動完成時釋放實例。 您必須在調用[init]或[copy]初始化實例後調用[autorelease]或[release]。

+0

我釋放_scoreLabel in dealloc方法。 你寫道,我有retainCount(2) - 但爲什麼保留計數是3? int counter = [[[self subviews] objectAtIndex:0] retainCount]; //這裏 – 2010-07-26 07:00:51

+0

haha​​ self subviews會產生新的子視圖 子視圖是不是自己的內部容器,它是內部容器的副本。 - 遵循doucments。 - @屬性(非原子,只讀,複製)NSArray *子視圖 所以調用[子視圖]然後新數組(自動釋放NSArray)。 你得到了retainCount(3)。 – TopChul 2010-07-27 04:18:58

相關問題