Что именно делает @synthesize?
Я видел следующий фрагмент кода:
//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;
//example.m
@synthesize mapView = mapView1
Вопрос: Какая связь между mapView и mapView1?
Создает ли метод set и get для mapView1?
Спасибо!
Ответы
Ответ 1
В вашем примере mapView1
- это переменная экземпляра (ivar), часть памяти, принадлежащая экземпляру класса, определенного в example.h
и example.m
. mapView
- это имя свойства. Свойства - это атрибуты объекта, который можно прочитать или установить с помощью точечной нотации: myObject.mapView
. Свойство не обязательно должно основываться на ivar, но большинство свойств. Объявление @property
просто сообщает миру, что существует свойство, называемое mapView
.
@synthesize mapView = mapView1;
Эта строка сообщает компилятору создать сеттер и 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;
Главное - иметь очень четкое концептуальное различие между иварами и свойствами. Они действительно две совершенно разные концепции.
Ответ 2
@synthesize
создает геттер и сеттер для переменной.
Это позволяет вам указать некоторые атрибуты для ваших переменных и когда вы @synthesize
это свойство переменной, сгенерирующей getter и setter для переменной.
Имя свойства может быть таким же, как имя переменной. Иногда люди хотят, чтобы они были разными, чтобы использовать их в init
или dealloc
или когда параметр передается с тем же именем переменной.
Ответ 3
Из документация:
Вы используете ключевое слово @synthesize, чтобы сообщить компилятору, что он должен синтезировать методы setter и/или getter для свойства, если вы не предоставите их в блоке @implementation.
Ответ 4
Как только я столкнулся с этой проблемой при редактировании устаревшего кода, я хочу сделать дополнительные примечания к существующим ответам, о которых нужно знать.
Даже с более новой версией компилятора иногда имеет значение, если вы опускаете @synthesize propertyName
или не.
В случае, если вы объявляете переменную экземпляра без подчеркивания при ее синтезе, например:
Заголовок:
@interface SomeClass : NSObject {
int someInt;
}
@property int someInt;
@end
Реализация:
@implementation SomeClass
@synthesize someInt;
@end
self.someInt
получит доступ к той же переменной, что и someInt
. Не использовать лидирующий знак подчеркивания для ivars не следует соглашениям об именах, но я просто пришел в ситуацию, когда мне пришлось читать и модифицировать такой код.
Но если теперь вы думаете: "Эй, @synthesize больше не важна, поскольку мы используем новый компилятор", вы ошибаетесь! Затем ваш класс будет иметь два ivars, а именно someInt
плюс автогенерированная переменная _someInt
. Таким образом, self.someInt
и someInt
больше не будут обращаться к тем же переменным. Если вы не ожидаете такого поведения, как я, это может вызвать у вас головную боль, чтобы узнать.
Ответ 5
В соответствии с документацией на Apple @Synthesize используется только для переименования переменных экземпляра. Например
@property NSString *str;
@synthesize str = str2;
Теперь в классе вы не можете использовать _str
, поскольку указанная выше строка переименовывает переменную экземпляра в str2
@property
позволяет объектам использовать объекты в других классах или, другими словами, делает объект общедоступным.
Ответ 6
Смотрите яблочные документы
В основном синтез создает методы setMapView и mapView, которые устанавливают и получают mapView1
Ответ 7
Он создает getter и setter для вашего объекта. Вы можете получить доступ к чему-то вроде этого:
MKMapView* m = object.mapView;
или
object.mapView = someMapViewObject
mapView1 - это имя ivar в классе, mapView - это имя метода (ов) getter/setter.