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开发者_Go百科:_scoreLabel];
int counter = [[[self subviews] objectAtIndex:0] retainCount]; // WHY 3?
return self;
}
-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
}
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.
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].
精彩评论