선언 된 속성에 해당 인스턴스 변수가 필요합니까?


101

Objective-C 2.0의 속성을 사용하려면 해당 인스턴스 변수를 선언해야합니까? 예를 들어, 나는 다음과 같은 일을하는 데 익숙합니다.

MyObject.h

@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end

MyObject.m

@implementation
@synthesize name;
@end

그러나 대신 이렇게하면 어떨까요?

MyObject.h

@interface MyObject : NSObject {
}
@property (nonatomic, retain) NSString *name;
@end

여전히 유효합니까? 그리고 이전 예와 다른 점이 있습니까?


두 번째 'MyObject.h'가 'MyObject.m'이 아닌 굵게 표시된 이유는 무엇입니까?
Ríomhaire 2013

답변:


93

Modern Objective-C 런타임 (iOS 3.x 이상 또는 64 비트 Snow Leopard 이상) 을 사용하는 경우 이와 같은 경우 속성에 대해 ivar를 정의 할 필요 가 없습니다 .

당신 @synthesize이 재산 일 때 , ivar는 사실상 당신을 위해 합성 될 것입니다. 이것은 "fragile-ivar"시나리오를 우회합니다. Cocoa with Love 에서 더 많은 것을 읽을 수 있습니다.


71

인터페이스에서 중괄호 사이, 중괄호 @property외부 또는 둘 다를 통해 인스턴스 변수를 공식적으로 선언 할 수 있습니다 . 어느 쪽이든 클래스의 속성이됩니다. 차이점은을 선언 @property하면 @synthesizegetter / setter를 자동으로 코딩하는 using을 구현할 수 있다는 것입니다. 예를 들어 자동 코더 설정 기는 정수를 초기화하고 0으로 부동합니다. 당신이 인스턴스 변수를 선언하고 해당를 지정하지 않으면 @property, 당신은 사용할 수 없습니다 @synthesize하고 있어야 자신의 게터 / 세터 물품.

고유 한 항목을 지정하여 언제든지 자동 코딩 된 getter / setter를 재정의 할 수 있습니다. 이것은 일반적으로 managedObjectContext느리게로드 된 속성 으로 수행됩니다 . 따라서 managedObjectContext속성으로 선언 한 다음 -(NSManagedObjectContext *)managedObjectContext메서드 도 작성합니다 . 인스턴스 변수 / 프로퍼티와 이름이 같은 메소드는 "getter"메소드입니다.

@property선언 방법은 당신에게 같은 다른 옵션을 허용 retain하고 readonly인스턴스 변수 선언 방법은하지 않습니다. 기본적으로 ivar는 오래된 방식이며 @property확장하여 더 멋지고 / 쉽게 만듭니다. 자신을 사용하여 참조 할 수 있습니다. 접두사 여부에 관계없이 이름이 해당 클래스에 고유 한 한 중요하지 않습니다. 그렇지 않고, 당신의 슈퍼 클래스가 당신과 같은 속성의 이름을 가지고 있다면, 당신이 말하는 이름을 지정하기 위해 self.name 또는 super.name처럼 말해야합니다.

따라서 ivar중괄호 사이에 s를 선언하는 사람이 점점 줄어들고 대신을 지정 @property하고 @synthesize. 당신은 할 수 없어 @synthesize대응하지 않고 구현 @property. 신디사이저는 @property사양 에있는 속성 유형 만 알고 있습니다. synthesize 문을 사용하면 속성의 이름을 바꿀 수 있으므로 코드 내에서 하나의 이름 (축약 형)으로 속성을 참조 할 수 있지만 .h 파일 외부에서는 전체 이름을 사용할 수 있습니다. 그러나 XCode가 현재 가지고있는 정말 멋진 자동 완성 기능을 사용하면 이점은 적지 만 여전히 존재합니다.

이것이 주변에 떠 다니는 모든 혼란과 잘못된 정보를 해결하는 데 도움이되기를 바랍니다.


이제는 @synthesize를 작성하는 것이 필수가 아닙니다. 그렇다면이 대답은 어떻게 유효합니까!
raaz

<code> @property ... @ synthesize </ code>를 선언 할 필요가 없습니다. synthesize를 사용하면 구현에서 getter / setter를 작성하지 않아도됩니다. 합성하지 않으면 자신의 게터 / 세터를 굴려야합니다
PapaSmurf 2013-10-26

2
@PapaSmurf 틀 렸습니다. 당신은 사용 @property하고 있지 사용 @synthesize그들에게 자신을 구현하지. 컴파일러는 synthesize더 이상 작성할 필요없이 자동으로 수행됩니다 .
jbrennan 2013

8

두 가지 방식으로 작동하지만 중괄호로 선언하지 않으면 xcode의 디버거에서 해당 값을 볼 수 없습니다.


3

문서에서 :

일반적으로 속성의 동작은 최신 런타임과 레거시 런타임 모두에서 동일합니다 (Objective-C 런타임 프로그래밍 가이드의 "런타임 버전 및 플랫폼"참조). 한 가지 주요 차이점이 있습니다. 최신 런타임은 인스턴스 변수 합성을 지원하지만 레거시 런타임은 지원하지 않습니다.

@synthesize가 레거시 런타임에서 작동하려면 속성의 이름과 호환 가능한 유형이 동일한 인스턴스 변수를 제공하거나 @synthesize 문에 다른 기존 인스턴스 변수를 지정해야합니다. 최신 런타임에서 인스턴스 변수를 제공하지 않으면 컴파일러가 자동으로 추가합니다.


3

XCode 4.4 이상을 사용하는 경우 인스턴스 변수 합성 코드가 생성됩니다.

아래와 같이 속성을 선언하면됩니다. 합성 코드와 인스턴스 변수 선언 코드를 생성합니다.

@property (nonatomic, strong) NSString *name;

합성 코드를 다음과 같이 생성합니다.

@synthesize name = _name;

_name을 사용하여 인스턴스 변수에 액세스 할 수 있습니다.

NSString* _name

그러나 읽기 전용 속성을 선언하면

@property (nonatomic, strong, readonly) NSString *name;

그것은 코드를 생성합니다

@synthesize name;

또는

@synthesize name = name; 

따라서 사용자가 직접 합성 코드를 작성할 수있는 모든 방법으로 접두사 "_"를 사용하여 인스턴트 변수 이름에 액세스해야합니다. 그러면 컴파일러가 코드를 생성합니다. 당신은 쓸 수 있습니다

@synthesize name = _name;

1

Objective-C 프로그래밍 언어 : 속성 구현 지시문

런타임에 따라 접근 자 합성 동작에는 차이가 있습니다 ( "런타임 차이"참조).

  • 레거시 런타임의 경우 인스턴스 변수는 현재 클래스의 @interface 블록에 이미 선언되어 있어야합니다. 속성과 이름이 같은 인스턴스 변수가 있고 해당 유형이 속성의 유형과 호환되는 경우 해당 변수가 사용됩니다. 그렇지 않으면 컴파일러 오류가 발생합니다.

  • 최신 런타임의 경우 (Objective-C 런타임 프로그래밍 가이드의 "런타임 버전 및 플랫폼"참조) 인스턴스 변수는 필요에 따라 합성됩니다. 동일한 이름의 인스턴스 변수가 이미 존재하는 경우이를 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.