2013-10-04 2 views
1

나는 BigNerdRanch 'Objective-C Programming from Aaron Hillegass'의 책에서 Objc를 연구 중이며, 나를 혼란스럽게하는이 문제가있다.왜 포인터의 클래스를 정의해야합니까?

필자는 컴파일러가 내가 말하는 변수의 종류를 알아야하므로 값을 할당하기 전에 var 유형을 선언해야한다는 것을 알고 있습니다.

int myNum = 10; 

좋아요. 그러나 ObjC 클래스에 관해서, 포인터가 _ 타입 바로 뒤에 선언해야한다면 포인터의 타입을 선언 할 이유가 무엇인지, 할당 할 때 그것을 초기화할까요?

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 

분명히 * dateFormatter 객체는 NSDateFormatter의 속성이며, 할당에 써야합니다. 왜 제가 처음에 그것을 선언해야합니까? 유형의 표현 'NSTimeZone *'와 '*는 NSString를'초기화 호환되지 않는 포인터 타입 '원인은 내가 엑스 코드가 명확 저를 경고

NSString *timeZone = [NSTimeZone systemTimeZone]; 

처럼 뭔가를하려고하면'.

나는 뭔가를 놓치고있는 것처럼 느껴집니다. 그것이 바보 같은 질문이라면 배울려고 죄송합니다.

+0

그냥 오브젝티브 C가 상속 C의 구문입니다. 걱정하지 마십시오. 중요하지 않습니다. –

+1

@PaulR : 변수를 정적으로 입력하는 것보다 id를 선언하는 것이 중요한 이점입니다. 내 대답보기 : http://stackoverflow.com/a/19190202/30461 –

답변

3

여기 진짜 질문은 "왜 포인터의 올바른 클래스를 정의해야합니까?"오히려입니다 ...

대답은 : 당신이 다른에 변수을 사용할 수 있습니다 문맥도. [NSTimeZone systemTimeZone] 메시지를 직접 보내면 컴파일러에서 형식을 추론 할 수 있지만 변수에 메시지를 보내면 어떻게됩니까? 당신이

id tz = [NSTimeZone systemTimeZone]; 

약한 형식의 갈 경우, 당신은 당신이 NSTimeZone *tz로 선언 된 경우는 수보다는 NSTimeZone *이 예상되는 tz를 사용하는 경우 컴파일러는 오류를 확인하기 위해 더 적은 기회가있다.

- (NSTimeZone *) userSpecifiedTimeZone { 
    id timeZone = [NSTimeZone timeZoneWithAbbreviation:self.timeZoneName]; 
    if (timeZone == nil) 
     timeZone = [NSTimeZone timeZoneWithName:self.timeZoneName]; 
    if (timeZone == nil) 
     timeZone = self.timeZoneName; 
    return timeZone; 
} 

이 버그를 참조하십시오

보다 선명한 예를 들어
+0

감사합니다.이 관점에서 훨씬 더 분명합니다. –

+0

@ H2CO3 Offtopic,하지만 100k까지 grats) – HAS

+0

@HAS 고마워요! :-) –

3

, 당신은 방법이 있다고 가정?

엑스 코드는 유형 id의 변수에 개체를 할당 완벽하게 유효한이기 때문에, 그것을 잡을되지 않으며, 그 반환 유형 모든 객체 유형이 방법에서 id를 반환하고, 이후 다른 그 id을 할당 id 변수를 사용하거나 호출 코드에서 메시지를 보내려고합니다.

이 버그는 런타임에 사용자가 일찍 잡을 수없는 경우와 사용자가 가짜 표준 시간대 이름을 입력 한 다음 그 시간을 사용하려고 시도하는 경우에만 발생합니다 영역 이름 (이 메서드의 결과로 잘못 반환 됨)을 NSTimeZone 개체로 반환합니다.

는 정적으로 입력 된 버전으로 비교 :

- (NSTimeZone *) userSpecifiedTimeZone { 
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:self.timeZoneName]; 
    if (timeZone == nil) 
     timeZone = [NSTimeZone timeZoneWithName:self.timeZoneName]; 
    if (timeZone == nil) 
     timeZone = self.timeZoneName; //Clang calls shenanigans here 
    return timeZone; 
} 

연타 바르게 NSTimeZone *로 입력 변수에 NSString *를 할당하는 의심스러운 것을 객체.

에 포인터의 클래스를 정의해야하지만 위에 표시된 것과 같은 버그의 가능성이 있습니다.

1

하지만 ObjC 클래스에 올 때, 내가 바로 = 후를 선언해야하는 경우, 때 ALLOC를 포인터의 유형을 선언하는 이유는 그리고는 init을?

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

당신은 두 번 포인터의 유형을 선언하지 않는. 이 성명서에는 많은 부분이 있습니다. 'NSDateFormatter'의 두 번째 발생은 NSDateFormatter 클래스에서 'alloc'메소드를 호출하는 반면 'NSDateFormatter'의 첫 번째 발생은 dataformatter가이 유형의 객체에 대한 포인터임을 컴파일러에 알리는 것입니다. 똑같은 단어, 완전히 다른 두 가지 의미.

가장 먼저 발생하는 것은 'NSDateFormatter'클래스에서 (클래스) 메서드 'alloc'을 호출하는 [NSDateFormatter alloc]입니다. 이 메서드는 'init'메서드가 호출 된 NSDateFormatter 개체의 (빈) 인스턴스를 반환합니다. 결과 객체에 대한 포인터는 'dateFormatter'변수에 저장되며, 컴파일러에게 NSDateFormatter 객체에 대한 포인터임을 알립니다. 이 같은 그것의

생각한다

NSDateFormatter *dateFormatter; Create a pointer to an NSDateFormatter object. 
newDate = [NSDateFormatter alloc]; Create an empty NSDateFormatter object by calling the class method alloc in NSDateFormatter 
[newDate init];     Initialise it by calling the onject's 'init' method 
dateformatter = *newDate;   Assign a pointer to it to my variable. 
관련 문제