2010-04-25 7 views
0

나는 데이터를 저장하는 두 개의 클래스 (class1과 class2)가 있으며 메소드는 없다. 일부 사용자 입력에 따라 두 클래스 중 하나에 설정되는 인스턴스 변수가있는 세 번째 클래스가 있습니다. 그래서, 세 번째 클래스에서 나는어떻게 인스턴스 변수를 동적으로 정의합니까?

NSObject *aClass; 

로 일반적으로 변수를 선언하고 런타임 중에 그것이 있어야 무엇으로 설정합니다. 그러나

aClass = [[Class1 alloc] init]; // or 
aClass = [[Class2 alloc] init]; 

, 내가 aClass

NSString *str = aClass.field1; 

에서 필드에 액세스하려고 할 때 그것은 나에게 오류를 제공합니다 : 멤버 '필드 1'에 대한 요청을 뭔가 아닌 구조 또는 노동 조합. Field1은 class1과 class2에서 모두 선언됩니다. 내가 캐스트를하려고 할 때

aClass = (Class1 *) aClass; 

같은 오류가 발생합니다. 내가 뭘 잘못하고 있는데, 더 좋은 방법이 있을까?

답변

4

속성은 컴파일러가 처리해야하는 클래스를 알고있을 때만 작동하기 때문입니다. NSObject에는 field1이라는 속성이 없으므로 작동하지 않습니다.

당신은, 그러나, 속성은 내재적으로 작성field1방법을 사용할 수 있습니다

NSString* str = [aClass field1]; 

을하지만 당신은 NSObject에 그 일을하는 경우, 경고를 방출하는 것입니다.

당신은 당신이하고 그들이 어떤 클래스 관계가없는 두 클래스 중 어떤 알 수없는 경우

, 난 당신이 대신 NSObject의의 id 유형을 사용하는 것이 좋습니다. id을 사용하면 컴파일러는 실패 할 가능성이있는 메서드 호출에 대한 경고를 표시하지 않지만 여전히 속성을 확인하지는 않습니다.

+0

감사합니다, 나는 점 표기법과 재산 방법을 사용하여 사이에 차이가 몰랐어요 이 문제에 관해서. 비록 그것을 직접 얻기 위해, aClass.field는 필드에 직접 접근합니다. 즉, [aClass field]가 메소드를 호출하는 동안 메서드가 호출되지 않았 음을 의미합니까? – Moses

+0

@ 모세 : 불행히도 그 행동은 그보다 덜 일관 적입니다. ObjC의 객체는 포인터입니다. 필드에 직접 액세스하려면'-> '연산자가 필요합니다.컴파일 타임에 유형을 판별 할 수없는 경우 속성이 실패하는 이유를 모르겠습니다. 속성 가져 오기 또는 설정은 실제로 메서드 호출이며 동일한 작업에 대한 도트 구문을 사용하지 않는 것이 완벽하게 작동합니다. 즉, aClass.field와 aClass 필드 모두 같은 일을해야합니다. 컴파일러가 객체의 유형을 알고있을 때만 첫 번째는 작동합니다. – zneak

1

모든 컴파일러는 aClass가 NSObject라는 것을 알고 있기 때문에 여러분은 그것만을 취급 할 수 있습니다. 그렇지 않으면 aClass가 NSString을 가리킬 때 field1에 액세스하려고하면 어떻게 될까요? 원하는 인스턴스 변수로 수퍼 클래스를 만들고 그 클래스의 클래스를 선언하십시오. 이렇게하면 aClass에 field1 변수가 포함되므로 가난한 컴파일러가 혼동하지 않고 계속 수행 할 수 있습니다.

NSObject에서 Class1로 캐스트 할 수없는 이유는 동일한 원칙을 따릅니다. aClass는 무엇이든 될 수 있으며, 컴파일러는 Class1에 어떤 방법을 알지 못합니다. 모든 aClass가 NSObject이기 때문에 다른 방식으로 캐스트 할 수 있지만 모든 NSObject가 aClass가 아닌 것은 아닙니다. : D

+1

Objective-C는 타입 안전하지 않으며 모든 것이 런타임에 해결됩니다. aClass가 NSString을 가리킬 때'field1'에 접근하려고하면, 정의되지 않은 메소드를 사용할 때 던져지는 것과 같은 예외를 던져야합니다. 내가 이상한 당신이 어떤 개체에 어떤 메서드를 호출 할 수 있고 그것이 컴파일 타임에 작동합니다 동의해야만하지만, 당신은 어떤 개체에 대한 속성을 사용할 수 없습니다. – zneak

+0

캐스팅에 대한 설명 주셔서 감사합니다. 한 가지 간단한 질문. 마치 Class1 * aClass = [[Class1 alloc] init]을 선언하고 aClass.field1을 호출하여 필드에 액세스하려고하면 컴파일러는 불평하지 않습니다. aClass가 NSObject로 선언되고 Class1에 캐스팅 되었습니까? 속성이 있는지 여부를 확인하면 유형에 따라 해당 속성을 수행하지 않습니까? – Moses

0

두 클래스를 모두 정의하려는 속성을 구현하는 하나의 기본 클래스에서 상속하지 않는 이유는 무엇입니까?

또는 두 클래스가, 그리고 대신 NSObject의 변수를 정의하는 구현하는 속성 범주를 만들 말 :

id <MyClassCategory> aClass; 
관련 문제