프로그램 충돌---autorelease 예외

1. 스스로 편의구조기를 실현할 때 매번 실행 프로그램에 빈 바늘 이상이 발생한다.코드와 이유는 다음과 같습니다.
+ (UILabel*)labelWithFrame:(CGRect)frame andText:(NSString*)text
{
    UILabel *label = [[UILabel alloc] initWithFrame:frame];
    label.text = text;
    return [label autorelease];
}
@implementation AAAController
- (void)init
{
     _label = [UILabel labelWithFrame:CGRectMake(30, 100, 100, 30) andText:@“  ”];
     [self.view addSubview:_label];
}


- (void)dealloc
{
     [_label release];
     _label = nil;
     [super dealloc];
}

@end

UIlabel의 편리한 구조기를 실현하고 싶지만, 페이지 전환을 실행할 때마다 빈 바늘 이상이 발생합니다.
오랫동안 찾다가 비로소 원인을 찾았다.
구조기는 autorelease 대상을 되돌려줍니다.label = [UIlabel label With Frame: CGRectMake(30, 100, 100, 30) andText: @ "이름"];다음,label이 가리키는 것은 autorelease 대상인데 인용 계수는 1을 추가하지 않았다. (지금은 1)이때는 위험합니다. autorelease 대상이 풀리면label도 없앴어요.만약에 autorelease 대상이 초기에 소각되지 않고 대상에게 dealloc 방법을 호출하면 방법에서 [label release]를 실행한 후에 해당하는 autorelease 대상을 소각한다.이후 autorelease 대상이 자동으로 소각되고 싶을 때 프로그램이 붕괴되고 컨트롤러에서도 오류가 발생하지 않습니다.이런 오류의 원인은 편의구조기 사용에 대한 정확한 이해가 없기 때문에 잘 이해하고 남용해서는 안 된다.
다음은 개선 방법입니다.
붕괴의 원인을 알았으니 (release를 한 번 더 썼다) 하기 쉽다.다음과 같습니다.
방법 1: dealloc를 수정합니다.[label release];label = nil; 삭제합니다.
방법2:장label = [UIlabel label With Frame: CGRectMake(30, 100, 100, 30) andText: @ "이름"];다음으로 수정됨:self.label = [UIlabel label With Frame: CGRectMake(30, 100, 100, 30) andText: @ "이름"];(setter 방법을 호출할 때 인용 계수가 1을 추가했기 때문) 다음에 dealloc를 호출하면label release 이후 autorelease 대상을 없애지 않습니다.(이런 방법은 프로그래밍 습관에 더욱 부합된다.
방법3: 편의구조기를 다음과 같이 수정한다.
    return [[label retain] autorelease];

좋은 웹페이지 즐겨찾기