2011-12-08 2 views
0

내가 코어 플롯의 소스를 통해 읽고 CPTColor이 코드를 가로 질러 달렸다 : 자체에 다른 값을 할당 initWithCGColor의 슈퍼 클래스에내 클래스의 지정된 초기화 프로그램을 self로 호출 한 결과를 할당해야합니까?

-(id)initWithCGColor:(CGColorRef)newCGColor 
{ 
    if ((self = [super init])) {    
     CGColorRetain(newCGColor); 
     cgColor = newCGColor; 
    } 
    return self; 
} 

-(id)initWithComponentRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha 
{ 
    CGFloat colorComponents[4]; 
    colorComponents[0] = red; 
    colorComponents[1] = green; 
    colorComponents[2] = blue; 
    colorComponents[3] = alpha; 
    CGColorRef color = CGColorCreate([CPTColorSpace genericRGBSpace].cgColorSpace, colorComponents); 
    [self initWithCGColor:color]; 
    CGColorRelease(color); 
    return self; 
} 

[self initWithCGColor:color];하면 결과를, 그 새로운 값은 initWithComponentRed:green:blue:alpha:에서 반환됩니다 ?

다른 말로하면 두 개의 init 메소드에서 self은 동일한 변수 두 개의 별개의 변수입니까? 코드가 변경되지 않는 한 self가 (. 전 당신이 컬러 캐시를 구현한다면) 변경 initWithComponentRed:green:blue:alpha:가 잘못된 개체를 반환한다면

답변

3

이 설정은 취약 할 수 있으며 Joe의 제안은 initWithComponentRed:...self을 할당하여 해당 값을 반환하면 해결됩니다.

모든 메서드는 호출 된 인스턴스를 가리키는 인수 self을 가져옵니다. 인수는 다른 변수와 동일하게 작동합니다. 거기에는 특별한 것이 없습니다. 그렇기 때문에 self을 할당 할 수 있으며 이니셜 라이저에 return을 명시해야하는 이유가 여기에 있습니다.

[super init]을 보내면 수퍼 클래스의 init 메서드를 사용하고 있지만 현재 인스턴스는 여전히 self으로 전달됩니다. Objective-C의 이니셜 라이저는받은 객체를 파괴하여 새 객체를 반환 할 수 있으므로 의 initWithColor:self이 가리키는 것과 동일한 객체가 아닌 initWithComponentRed:...의 객체가 될 수 있습니다. 당신이 새로운, 제대로 초기화 객체를 가리 키도록 self을 다시 할당하지 않기 때문에 즉, 이런 경우

, 당신은 initWithComponentRed:...에서 초기화되지 않은 객체를 반환됩니다.

슈퍼 클래스가 내가 설명한 대체를 수행 할 수있는 경우에만 실제적인 문제 일 뿐이지 만 AFAIK는 재 할당을하지 않을 이유가 없습니다. 그들이 alloc 시간에 할 필요가 얼마나 큰 모르기 때문에


* 컬렉션은, 예를 들어,이 작업을 수행; 작은 정수를 나타내는 인스턴스의 값을 캐싱 했으므로 NSNumber도이 작업을 수행한다고 생각합니다.

+0

그것이 내가 생각한 것이지만 그것을 확인하고 싶었습니다. 확실하게하기 위해, 나는 수퍼 클래스가'self'를 릴리즈하고 알파 채널이 0이면 nil을 반환하는 간단한 테스트 프로그램을 작성했습니다.이 경우 하위 클래스의 초기화 프로그램은 올바른 값 'nil'대신 잘못된 참조를 반환합니다. – SSteve

+0

@SSteve : 좋아요. 기꺼이 도와 드리겠습니다. –

+2

정확합니다. 이 문제가 해결되었습니다. http://code.google.com/p/core-plot/source/detail?r=082ab717a53aa158003b9d8cdd376faeef3fd9ce를 참조하십시오. –

2

번호 :

... 
    self = [self initWithCGColor:color]; 
    CGColorRelease(color); 
    return self; 
} 
0

self 항상 같은 객체를 참조. "변수"가 아니라 언어 핵심어입니다. 하나의 초기화 프로그램이 다른 하나 다음에 호출되면 객체가 간단히 변경됩니다.

NB : 그렇지 않으면 부류가 "성격을 나눕니다";-)가됩니다.

+1

이것은 실제로 올바르지 않습니다. 'self'_is_ a 변수; 모든 메소드에 대한 내재 된 인수입니다. 현재 인스턴스가 값으로 전달되지만 로컬 '자체'포인터를 재 지정할 수 있습니다. 이것은 다른 방법에서 일어나는 일에 영향을 미치지 않습니다. –

관련 문제