문제

나는 nsobject의 서브 클래스 인 'classa'를 정의하고 사용하는 프레임 워크를 사용하고 있습니다. 일부 변수와 기능을 추가하고 싶습니다. 자연스럽게 'classa'의 서브 클래스 인 'classb'를 만들었습니다.

이제 내 문제는 이것입니다. 이 프레임 워크 내의 많은 방법은 'classa'의 인스턴스를 내 서브 클래스로 캐스팅하고자합니다.

예를 들어이 방법을 사용하십시오.

- (ClassA *)doSomethingCool:(int)howCool

이제 내 코드에서 나는 이것을 시도한다 :

ClassB * objB;
objB = (ClassB *)doSomethingCool(10); 

NSLog(@"objB className = %@", [objB className]);

이것은 잘 실행됩니다. 컴파일 또는 런타임 오류가 없습니다. 그러나 나에게 정말 이상한 것은 출력입니다.

>> "objB className = ClassA"

캐스팅은 분명히 실패했습니다. 이 시점에서 무슨 일이 있었는지 확실하지 않습니다 ... OBJB는 'classb'로 입력되지만 클래스 이름은 'classa'이며 'classb'메소드에 응답하지 않습니다.

이것이 어떻게 가능한지 잘 모르겠습니다 ... 여기서 내가 뭘 잘못하고 있는지 아는 사람이 있습니까?

내가 묻는 것과 정반대 인 비슷한 게시물을 찾았습니다. 여기

도움이 되었습니까?

해결책

Objective-C에서 객체 변수를 캐스팅하는 것은 일반적으로 실수입니다 (옳은 경우 몇 가지 경우가 있지만 이런 종류의 경우에는 결코 없습니다). 당신이 물건을 캐스팅하지 않는다는 것을 주목하십시오 - 당신은 캐스팅하고 있습니다 바늘 물체에. 그런 다음 유형의 포인터가 있습니다 ClassB*, 그러나 여전히 동일한 Classa 인스턴스를 가리 킵니다. 지적한 것은 전혀 변하지 않았습니다.

classa 인스턴스를 classb로 변환하려면 classa에서 classb 인스턴스를 생성 할 수있는 classb 생성자 메소드를 작성해야합니다. 인스턴스 변수를 실제로 추가 해야하는 경우 이것이 최선의 선택 일 수 있습니다.

그러나 Jason이 말했듯이, 종종 카테고리를 먼저 시도하는 것이 좋습니다.

다른 팁

슈퍼 클래스를 서브 클래스로 캐스트 할 수는 없습니다. 실제로 추가 된 변수/속성 또는 메소드를 구현하지 않습니다. 서브 클래스에서 정의하는 메소드로 메시지를 보내려고하자마자 런타임 예외가 발생하고 응용 프로그램이 종료됩니다. 한 방향으로 안전하게 캐스트 할 수 있습니다.보다 구체적으로보다 일반적인 것까지. 즉, Classa의 방법과 속성 만 사용하여 ClassB를 Classa에 안전하게 캐스트 할 수 있지만 다른 방법은 아닙니다.

이런 식으로 생각하십시오 : 당신은 자동차 (부모 클래스)와 Fourdoorsedan (서브 클래스)이 있습니다. 모든 자동차에는 엔진과 두 개의 문이 있습니다. 자, 당신이 어딘가에서 차를 얻고 있다고 가정 해 봅시다. 그리고 그것이 당신이 그것에 대해 알고있는 전부라고 가정 해 봅시다. 당신은 운영자에게 자동차가 Fourdoorsedan이라고 말하지만 실제로는 그렇지 않다는 것이 밝혀졌습니다. 운영자가 다음을 수행 할 때 : OpenBackPassengerDoor, 어떻게됩니까? 문이 두 개뿐입니다 !! 여기와 동일합니다.

Classa에 약간의 기능을 추가하려면 Objective-C 카테고리를 확인하십시오. 아마도 원하는 것이며 캐스팅이 필요하지 않습니다. 그러나 문서를주의 깊게 읽으십시오. 왜냐하면 그들은 경고가 없기 때문입니다.

기존 객체에 메소드를 추가하려면 서브 클래싱이 올바른 방법이 아닙니다. 라는 언어 기능을 사용하여 기존 클래스 (및 인스턴스)에 메소드를 추가 할 수 있습니다. 범주.

예시:

//"ClassA+doSomethingCool.h"
@interface ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool;
@end


//"ClassA+doSomethingCool.m"
@implementation ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool
{

}
@end

캐스팅은 한 유형의 물체에서 다른 유형으로 변환되지 않습니다. 공장 패턴을 사용하지 않는 한 일부 라이브러리가 객체 유형을 변경하고 다른 유형의 객체를 만들 수 없습니다.

반환 된 객체에서 서브 클래스 메소드 중 하나를 호출하면 어떻게됩니까?

ClassB * objB;
objB = (ClassB *)doSomethingCool(10);
[objB subClassMethod];

OBJ-C는 꽤 자유롭고 유형으로 잃어 버리기 때문에 미리 유형을 알 필요조차 없습니다. 모든 ClassB 참조를 ID에 변경할 수 있습니다. 예상 유형이 있다는 것을 아는 것이 더 안전하다는 것을 알고 있지만 코드가 정확하다면 중요하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top