2010-03-05 4 views
47

이 애플의 아이폰 유틸리티 Aplication '템플릿 수정되지 않은 코드 :오브젝티브 C는 '자기'를 사용하면

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

MainViewController *aController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil]; 
self.mainViewController = aController; 
[aController release]; 

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 
[window addSubview:[mainViewController view]]; 
[window makeKeyAndVisible]; 

} 

mainViewControlleraController에 할당되면, self 키워드가 지정됩니다

self.mainViewController = aController; 
mainViewController의 프레임이 설정되어있는 경우

는 그러나 self 키워드가 필요하지 않습니다 :

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 
내가 첫 번째 예에서 self 키워드를 제거하면

, 프로그램은 메시지와 함께 충돌 : 나는 두 번째 예제에 self 키워드를 추가하는 경우

objc[1296]: FREED(id): message view sent to freed object=0x3b122d0 

이 프로그램이 잘 실행됩니다.

누군가 self이 첫 번째 경우에는 필요하지만 두 번째 경우에는 필요하지 않은 이유를 설명 할 수 있습니까? 두 경우 모두 mainViewController이 동일한 인스턴스 변수를 참조하고 있다고 가정합니다.

+0

이 질문에 대한 답변 읽기 : http://stackoverflow.com/questions/2302891/self-instance-var-performance-hit – Felixyz

답변

47

self를 사용하면 ivar을 직접 변경하는 대신이 변수에 대한 클래스의 "setter"가 호출됩니다.

mainViewController = aController; 

단지 UIApplication의 setMainViewController에 내장 할 수있는 추가 코드를 스킵 직접 mainViewController 인스턴스 변수를 변경합니다 한편

[self setMainViewController:aController]; 

:

self.mainViewController = aController; 

은 동등하다 방법, 예를 들어 오래된 객체를 해제하고 새 객체를 유지하며 내부 변수를 업데이트하는 등의 작업을 수행 할 수 있습니다.

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 

로 확장됩니다 : 당신의 프레임에 접근, 당신은 여전히 ​​전화하는거야 세터 방법은 경우

미래 증거로,

[[mainViewController view] setFrame:[[UIScreen mainScreen] applicationFrame]]; 

이상적으로 코드를, 당신은 또한해야 이 값을 검색 할 때 self.mainViewController (또는 [self mainViewController])을 사용하십시오. 일반적으로 클래스는 "getter"메소드에서 "setter"보다 중요한 코드를 가질 확률이 훨씬 적지 만 향후 직접 액세스하면 Cocoa Touch의 차후 버전에서 무언가가 깨질 수 있습니다.

+1

클래스 내에서 직접 ivar에 액세스하는 경우, 향후 업데이트로 인해 어떻게 문제가 발생할 수 있는지 확인하십시오.코드를 리팩터링해야한다면 번거 로움을 피하기 위해 접근자를 사용하는 것이 여전히 좋은 원칙이지만, 간단한 경우 클래스가 값을 가져올 때 자신의 ivars에 직접 액세스하는 것이 문제는 아니라고 생각합니다. 설정을 위해서는 항상 setter 메서드를 사용합니다. – Felixyz

+5

getter 및 setter 메서드 자체 내에서를 제외하고 항상 self를 사용해야합니다 (직접 작성하는 경우). 이렇게하면 개체 유지가 자동으로 처리됩니다. 또한 iVar의 유효성을 검사하거나 if가 항상 존재하지 않도록하는 등의 작업을 수행하는 사용자 정의 코드를 제공 할 수 있습니다. getter 및 setter 메서드 외에도 iVar에 직접 액세스 할 수있는 좋은 이유가있을 수 있습니다. 비록 많은 사람들이 보통 실수 나 게으름에서 빠져 나옵니다. – TechZen

+3

나는 dealloc에서 직접 ivar에 액세스하는 적어도 하나의 예외가 있다고 생각합니다. 그 외에도 getters와 setter와 함께 항상 자아를 사용해야한다고 생각합니다. –

9

self 키워드는 값에 직접 액세스하는 대신 getter/setter 속성을 사용하고 있음을 나타냅니다. 동기화를 사용하여 getter/setter를 자동 생성하도록 한 경우 첫 번째 예제에서 self를 사용해야합니다. 포인터가 할당 된 대신 객체가 유지되기 때문입니다.

+0

여기 아무도 정말로 설명하지 않았습니다. 자기 변수가 무엇인지. 나는 이것이 이것이 질문의 일부라고 생각한다. – Fab1n

+4

self는 C++와 비슷한이 포인터로 class의 주소를 포함합니다. – Subrat