@synthesize는 정확히 무엇을합니까?


148

다음 코드 조각을 보았습니다.

//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;

//example.m
@synthesize mapView = mapView1

mapView과 의 관계는 무엇입니까 mapView1? 에 대한 setget메소드를 작성합니까 mapView1?


1
업데이트 : 최신 도구 세트로 @synthesize는 이제 (거의) 필요하지 않습니다. 다른 스택 오버플로 질문에 대한 답변을 참조하십시오 .
Ali Beadle

답변:


228

귀하의 예 에서 및에 정의 된 클래스의 인스턴스에 속하는 메모리 저장소 mapView1인스턴스 변수 (ivar)가 있습니다. 속성 의 이름입니다 . 속성은 점 표기법을 사용하여 읽거나 설정할 수있는 객체의 속성입니다 . 속성은하지 않습니다 바르 기반으로 할 수 있지만, 대부분의 속성이다. 선언은 단순히라는 속성이 있음을 세계에 알려줍니다 .example.hexample.mmapViewmyObject.mapView@propertymapView

@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와 속성을 매우 명확하게 개념적으로 구분하는 것입니다. 그들은 실제로 두 가지 매우 다른 개념입니다.


31

@synthesize 변수에 대한 getter 및 setter를 작성합니다.

이를 통해 변수에 대한 일부 속성을 지정할 수 있으며 해당 특성을 변수에 지정 @synthesize하면 변수에 대한 getter 및 setter가 생성됩니다.

특성 이름은 변수 이름과 동일 할 수 있습니다. 때때로 사람들이 그것을 사용하기 위해이 다를 수하고자 init하거나 dealloc또는 매개 변수가 같은 변수의 이름으로 전달 될 때.


16

에서 문서 :

@synthesize 키워드를 사용하여 @implementation 블록 내에 속성을 제공하지 않으면 속성에 대한 setter 및 / 또는 getter 메서드를 합성해야한다고 컴파일러에 알립니다.


8

레거시 코드를 편집 할 때이 문제가 발생하면 알고 있어야하는 기존 답변에 추가 메모를하고 싶습니다.

최신 컴파일러 버전을 사용하더라도 생략 @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.someIntsomeInt더 이상 동일 변수를 처리하지 않을 것이다. 내가 한 것과 같은 행동을 기대하지 않으면 두통이 생길 수 있습니다.


"synchronize"! = "synthesize"?
jameshfisher

예,이 두 가지 개념이 있습니다. @synchronize속성에 액세스 할 때 스레드를 동기화하는 방법에 대한 지시문이며 @synthesizegetter 및 setter를 통해 속성을 인스턴스 변수에 바인딩하기위한 것입니다.
Lars Blumberg

1
jameshfisher의 의견은 귀하가 귀하의 답변에서 동기화 및 합성을 혼동했다는 것을 경고하기위한 것입니다. 두 가지를 서로 바꿔서 사용할 수 있습니다.
메이플

1
알려 줘서 고마워! 나는 존재하지 않는 @synchronize 키워드를 사용하지 않도록 답변을 업데이트했습니다.
Lars Blumberg

이 경우 xcode 10은이 문제에 대해 경고합니다 Autosynthesized property 'someInt' will use synthesized instance variable '_someInt', not existing instance variable 'someInt'. (이 경고가 어떤 xcode 버전에 추가되었는지는 잘 모르겠습니다.)
zwcloud

7

애플 문서에 따라 @Synthesize 는 인스턴스 변수의 이름을 바꾸는 데만 사용됩니다. 예를 들어

@property NSString *str;

@synthesize str = str2; 

이제 클래스 _str에서 위의 줄이 인스턴스 변수의 이름을 다음과 같이 바꿀 수 없습니다.str2

@property 다른 클래스의 객체가 객체를 사용할 수있게하거나, 즉 객체를 공개합니다.


3
분명히 Xcode 4.4부터 Clang은 선언 된 속성의 자동 합성을 지원합니다. 따라서 대부분의 경우 @synthesize가 더 이상 필요하지 않습니다. useyourloaf.com/blog/2012/08/01/…
huyz

5

@interface에서 속성을 만들면 해당 속성은 _propertyName이라는 인스턴스 변수에 의해 자동으로 반환됩니다. 따라서 firstName이라는 속성을 만들면 장면 컴파일러 뒤에 기본적으로 _firstName이라는 인스턴스 변수가 만들어집니다. 컴파일러는 또한 getter 및 setter 메소드 (즉, firstName, setFirstName)를 작성합니다.

이제 @synthesize firstName으로 속성을 합성하면 컴파일러가 firstName으로 내 인스턴스 변수 (_firstName)의 이름을 바꾸도록 지시합니다. 백업 된 인스턴스 변수의 이름을 다른 이름으로 바꾸려면 속성 이름 (예 : @synthesize firstName = myFirstName)을 합성하는 동안 다른 이름을 지정하면됩니다. 이렇게하면 속성이 myFirstname이라는 인스턴스 변수로 백업됩니다.

즉, @synthesize는 대부분 속성에 의해 백업되는 인스턴스 변수의 이름을 바꾸는 데 사용됩니다.


2

사과 문서를 참조하십시오

기본적으로 합성은 mapView1을 설정하고 얻는 setMapView 및 mapView 메소드를 작성합니다.


2

객체에 대한 getter 및 setter를 만듭니다. 다음과 같은 방법으로 액세스 할 수 있습니다.

MKMapView* m = object.mapView;

또는

object.mapView = someMapViewObject

mapView1은 클래스에서 ivar의 이름이고 mapView는 getter / setter 메소드의 이름입니다.

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