다음 코드 조각을 보았습니다.
//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;
//example.m
@synthesize mapView = mapView1
mapView
과 의 관계는 무엇입니까 mapView1
? 에 대한 set
및 get
메소드를 작성합니까 mapView1
?
다음 코드 조각을 보았습니다.
//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;
//example.m
@synthesize mapView = mapView1
mapView
과 의 관계는 무엇입니까 mapView1
? 에 대한 set
및 get
메소드를 작성합니까 mapView1
?
답변:
귀하의 예 에서 및에 정의 된 클래스의 인스턴스에 속하는 메모리 저장소 mapView1
인 인스턴스 변수 (ivar)가 있습니다. 속성 의 이름입니다 . 속성은 점 표기법을 사용하여 읽거나 설정할 수있는 객체의 속성입니다 . 속성은하지 않습니다 이 바르 기반으로 할 수 있지만, 대부분의 속성이다. 선언은 단순히라는 속성이 있음을 세계에 알려줍니다 .example.h
example.m
mapView
myObject.mapView
@property
mapView
@synthesize mapView = mapView1;
이 줄은 컴파일러에게에 대한 setter 및 getter를 작성하고 mapView
라는 ivar을 사용해야한다고 지시합니다 mapView1
. = mapView1
부분이 없으면 컴파일러는 속성과 ivar의 이름이 같다고 가정합니다. (이 경우 ivar이 없기 때문에 컴파일러 오류가 발생합니다 mapView
.)
이 @synthesize
문장 의 결과는 이 코드를 직접 추가 한 경우와 비슷합니다.
-(MKMapView *)mapView
{
return mapView1;
}
-(void)setMapView:(MKMapView *)newMapView
{
if (newMapView != mapView1)
{
[mapView1 release];
mapView1 = [newMapView retain];
}
}
해당 코드를 클래스에 직접 추가하면 @synthesize
명령문을
@dynamic mapView;
가장 중요한 것은 ivar와 속성을 매우 명확하게 개념적으로 구분하는 것입니다. 그들은 실제로 두 가지 매우 다른 개념입니다.
레거시 코드를 편집 할 때이 문제가 발생하면 알고 있어야하는 기존 답변에 추가 메모를하고 싶습니다.
최신 컴파일러 버전을 사용하더라도 생략 @synthesize propertyName
하거나 생략하면 때로는 차이가 있습니다. .
이 경우 , 밑줄 없이 인스턴스 변수를 선언하면서 인스턴스 변수 를 계속 합성합니다 (예 :
헤더:
@interface SomeClass : NSObject {
int someInt;
}
@property int someInt;
@end
이행:
@implementation SomeClass
@synthesize someInt;
@end
self.someInt
와 같은 변수에 액세스합니다 someInt
. ivars에 밑줄을 사용하지 않으면 명명 규칙을 따르지 않지만 그러한 코드를 읽고 수정 해야하는 상황에 빠졌습니다.
그러나 이제 "새로운 컴파일러를 사용할 때 @synthesize가 더 이상 중요하지 않다"고 생각 하면 틀린 것입니다! 그러면 클래스는 두 개의 ivar , 즉 someInt
자동 생성 _someInt
변수 를 갖게됩니다 . 따라서 self.someInt
과 someInt
더 이상 동일 변수를 처리하지 않을 것이다. 내가 한 것과 같은 행동을 기대하지 않으면 두통이 생길 수 있습니다.
@synchronize
속성에 액세스 할 때 스레드를 동기화하는 방법에 대한 지시문이며 @synthesize
getter 및 setter를 통해 속성을 인스턴스 변수에 바인딩하기위한 것입니다.
Autosynthesized property 'someInt' will use synthesized instance variable '_someInt', not existing instance variable 'someInt'
. (이 경고가 어떤 xcode 버전에 추가되었는지는 잘 모르겠습니다.)
애플 문서에 따라 @Synthesize 는 인스턴스 변수의 이름을 바꾸는 데만 사용됩니다. 예를 들어
@property NSString *str;
@synthesize str = str2;
이제 클래스 _str
에서 위의 줄이 인스턴스 변수의 이름을 다음과 같이 바꿀 수 없습니다.str2
@property
다른 클래스의 객체가 객체를 사용할 수있게하거나, 즉 객체를 공개합니다.
@interface에서 속성을 만들면 해당 속성은 _propertyName이라는 인스턴스 변수에 의해 자동으로 반환됩니다. 따라서 firstName이라는 속성을 만들면 장면 컴파일러 뒤에 기본적으로 _firstName이라는 인스턴스 변수가 만들어집니다. 컴파일러는 또한 getter 및 setter 메소드 (즉, firstName, setFirstName)를 작성합니다.
이제 @synthesize firstName으로 속성을 합성하면 컴파일러가 firstName으로 내 인스턴스 변수 (_firstName)의 이름을 바꾸도록 지시합니다. 백업 된 인스턴스 변수의 이름을 다른 이름으로 바꾸려면 속성 이름 (예 : @synthesize firstName = myFirstName)을 합성하는 동안 다른 이름을 지정하면됩니다. 이렇게하면 속성이 myFirstname이라는 인스턴스 변수로 백업됩니다.
즉, @synthesize는 대부분 속성에 의해 백업되는 인스턴스 변수의 이름을 바꾸는 데 사용됩니다.