2010-06-18 3 views
2

인터페이스 빌더에서 IBOutlet을 UI 컨트롤에 연결된 필드로 사용하는 많은 iPhone 예제를 보았습니다.이 필드는 인터페이스 클래스의 속성으로 정의됩니다. 예를 들어, 다음 코드는 애플의 예제 코드에서 유사한 것들이다 : 나는 내 컨트롤러 클래스 IBOutlets에 인터페이스 빌더에 레이블을 연결하는 시도IBOutlet 필드의 속성을 정의해야 할 필요가 있습니까?

// in .h file 
@interface MyViewController : UIViewController { 
    IBOutlet UILabel* _firstName; 
    IBOutlet UILabel* _lastName; 
    ... 
} 

@property (nonatomic, retain) UILabel* firstName; 
@property (nonatomic, retain) UILabel* lastName; 
... 
@end 

// in .m file 
@implementation MyViewController { 
@synthetic firstName = _firstName; 
@synthetic lastName = _lastName; 
... 
@end 

와 나는 _firstName 및 _lastName을 볼 수 있습니다. 연계는 Interface Builder에서 직접 인터페이스 클래스 멤버 (@private 지시문을 배치하는 경우 개인적인 경우도 포함)이기 때문에. 해당 입력란의 속성을 정의해야합니까?

실제로 이러한 속성을 제거하려고했는데 코드가 정상적으로 작동하는 것으로 보입니다. 프로퍼티를 정의함으로써, 클래스는 그것들을 public으로 노출합니다. 나는 내 코드 내외부의 재산으로 그 용도 나 이유가 없다. 내 질문은이 연습, 속성으로 필드를 정의하는 것이 필요한 경우? Objective-C 개념이나 프레임 워크에서 호출 될 수있는 메모리 관리와 같은 것을 놓치고 있습니까?

+0

[IBOutlet을 보유하지 않으면 어떻게됩니까?] (http://stackoverflow.com/questions/1250518/what-happens-if-i-dont-retain-iboutlet) – Vladimir

+0

그리고 다음을 선언 할 수 있습니다. 구현 파일의 클래스 범주에있는 속성을 사용하므로 해당 속성은 공용 메서드로 노출되지 않습니다. – Vladimir

+0

ivars에 밑줄을 붙이면 Apple에 의해 크게 권장되지 않으며 문제가 발생할 수 있습니다. 자신의 내부 클래스가 이름 충돌을 피하기 위해이 클래스를 사용하기 때문입니다. –

답변

1

제가 언급 한대로 Jeremie Wekdin은 내 질문에 어떻게 든 이 중복 된입니다. 유사한 질문과 답변을 통해 nib/xib 파일을 사용하는 경우 고려해야 할 메모리 문제가 있음을 알 수 있습니다.

요약하면 Cocoa는 setOutletName을 먼저 찾고 속성 메서드를 사용하여 UI 컨트롤 개체를 설정합니다. 그렇지 않으면 Cocoa는 set을 클래스 멤버 변수로 보내고 그대로 유지합니다. 이는 제출 된 객체가 dealloc 메소드에서 해제되어야 함을 의미합니다.

괜찮습니다. 그러나, 내 질문의 경우 내 필드 변수를 _firstName 및 firstName 같은 해당 속성 이름에서 다른 이름을 갖습니다. 이 경우 코코아가 속성 메소드를 파악할만큼 똑똑하지 않으며 nib/xib에서 검색된 객체가 클래스 멤버에 직접 설정되어 있다고 생각합니다.

// in .m file 
@implementation MyViewController { 
@synthetic firstName = _firstName; 
- (void) setFirstName:(UILabel*) value { 
    NSLog("_firstname: %@", _firstName); 
    [_firstname autorelease]; 
    _firstName = [value retain]; 
} 

그럼 난 내 시야를로드, 로그 메시지가 엑스 코드의 출력 콘솔에 표시되지 않습니다

그것을 확인하기 위해, 나는 세터를 덮어 씁니다. 그러나 변수 이름과 속성 이름을 동일하게 유지하면됩니다. 출력 콘솔에서

// in .h 
@interface MyViewController : UIViewController { 
IBOutlet UILabel* firstName; 
... 
} 

@property (nonatomic, retain) UILabel* firstName; 
... 
@end 

// in .m file 
@implementation MyViewController { 
@synthetic firstName; 
- (void) setFirstName:(UILabel*) value { 
    NSLog("firstName: %@", firstName); 
    [firstName autorelease]; 
    firstName = [value retain]; 
} 
... 
@end 

를보기 쇼는, 내가 볼 때 : 중복 (가) QA가 제안한 것처럼, 나는 Appl's Resource Programming Guide을 읽을

firstName: (null) 

나는 세터가 호출 될 때 참조 할. Nib 개체 수명주기, 개체로드 프로세스 및 # 3 Outlet 연결 섹션의 문서를 찾습니다. Mac OS X 및 iPhone OS에는 콘센트를 객체에 연결하는 다양한 방법이 있다는 것을 알아야합니다.

@implementation MyViewController { 
@synthetic firstName = _firstName; 
- (void) setValue:(id) value forKey:(NSString*) key { 
    NSLog("forKey: %@; value: %@", key, value); 
    if ([key isEqualToString:@"_firstName"]) 
    // It should then call the accessor or property 
    // self._firstName = value; 
    // to set value, like the follow codes in the setter: 
    [_firstName autorelease]; 
    _firstName = [value retain]; 
    } 
    ... 
} 
... 
@end 
난 다시 내 코드를 컴파일

내가 모든 속성 setter를 참조 않았다

그래서 나는 다음과 같은 코드를 시도했다 "아이폰 OS에서, 펜촉 로딩 코드는 각각의 콘센트를 다시 연결 setValue:forKey: 방법을 사용" _firstName 키를 포함한 호출.Apple의 문서에서 계속 :

"그 메소드 (setValue : forKey :)는 마찬가지로 적절한 접근 자 메소드를 찾고 실패 할 때 다른 수단으로 넘어갑니다."

내 경우에 (속성 이름이 콘센트 변수 이름과 다른 이유는)이 속성이 Cocoa에 의해 호출되는 이유를 설명합니다.

결론적으로 필드 컨트롤에 대해 IBOutlet 및 nib/xib를 사용하여 뷰를로드 할 때 메모리 문제가 발생합니다. Cocoa가 정의 된 접근 자 또는 객체를 처리하는 필드 변수를 설정하는 속성을 찾도록하는 것이 좋을 것입니다. IBOutlet 필드 변수에 대한 속성을 정의하면 둘 다 동일해야합니다. 결과적으로이 코드는 Mac OS X 및 iPhone OS 모두에서 작동합니다.

관련 문제