views:

43

answers:

3

Why counter variable equals 3, not 2?

@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  A: 

Make sure closing braces ']' on sending message-

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

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

now check and let us know for further problem.

Sadat
I'm sorry to post not correct version of code.I have edited first message with correct one.And I still have counter equals 3, not 2
artur_i_am
A: 

I think that U don't know about the retain mechanism.

It's very simple.

initializer [init] and [copy] methods should increase retainCount. ==> retainCount == 1 after calling [addSubview], self has new retain of _scoreLabel, then retainCount + 1 ==> retainCount == 2

so, U got the retainCount(2)

U should change your code with the following.

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

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

or show call release like this

==> [_scoreLabel release];

[autorelease] methods would release the instance when event driving complete. You must call [autorelease] or [release] after initialize a instance with call [init] or [copy].

TopChul
I release _scoreLabel in dealloc method.You wrote, that I have got retainCount(2) - but WHY retain count is 3?int counter = [[[self subviews] objectAtIndex:0] retainCount]; //here
artur_i_am
haha self subviews would make new array of subviews.the subviews is not self internal container, It's copy of internal container.- following doucments.- @property(nonatomic, readonly, copy) NSArray *subviewsso call [subviews] then new array(autoreleased NSArray).U got the retainCount(3).
TopChul
+1  A: 

-retainCount is not reliable.

Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

In your case, the particular reason is because -subview also causes all subviews to be retained once, by copying the value of .layer.sublayers to a new array*:

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

There is no need to worry about it, as the array is autoreleased and the retainCount will drop back to 2 later. All you need is to ensure is the net retain count cause by the current function is consistent with the ownership status.


*: The particular implementation of .subviews is:

-(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
 }
KennyTM
Whoah, is that reverse-engineered Apple copyrighted code there?
JBRWilkinson