2010-07-16 3 views
136

Я видел следующий фрагмент кода:Что именно делает @synthesize?

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

//example.m 
@synthesize mapView = mapView1 

Вопрос: Какое отношение между MAPview и mapView1 есть? Создать и Получить метод для mapView1?

Спасибо!

+1

Обновление: но с последним набором инструментов @synthesize теперь (почти) никогда не требуется. См. Ответ на [Другой вопрос переполнения стека] (http://stackoverflow.com/questions/17019798/about-naming-the-instance-variable-in-objective-c/17019883#17019883). –

ответ

29

@synthesize создает геттер и сеттер для переменной.

Это позволяет указать некоторые атрибуты для ваших переменных, и когда вы присвоите этому свойству переменную, вы генерируете getter и setter для переменной.

Имя свойства может быть таким же, как имя переменной. Иногда люди хотят, чтобы он был другим, чтобы использовать его в init или dealloc или когда параметр передается с тем же именем переменной.

16

От the documentation:

Вы используете @synthesize ключевое слово, чтобы сообщить компилятору, что он должен синтезировать сеттер и/или методов получения для свойства, если не поставить их в блоке @implementation.

2

См the apple docs

В основном синтезируют создает setMapView и MAPview методы, которые устанавливают и получают mapView1

2

Он создает геттер и сеттер для вашего объекта. Вы можете получить доступ к что-то вроде этого:

MKMapView* m = object.mapView; 

или

object.mapView = someMapViewObject 

mapView1 это имя Ивар в классе, MAPview это имя метода (ов) геттер/сеттер.

199

В вашем примере, mapView1 является экземпляр переменной (Ивар), часть памяти, в которой принадлежит к экземпляру класса, определенного в example.h и example.m. mapView - это имя . Свойства - это атрибуты объекта, которые могут быть прочитаны или заданы с использованием точечной нотации: myObject.mapView. В собственности нет есть, чтобы быть основанным на ivar, но большинство свойств. Объявление @property просто говорит миру, что есть свойство, называемое mapView.

@synthesize mapView = mapView1;

Эта строка указывает компилятору создать и присваивателя для mapView, и что они должны использовать Ивар под названием mapView1. Без части = mapView1 компилятор предположил бы, что свойство и ivar имеют одинаковое имя.(В данном случае, это будет производить ошибку компиляции, так как нет Ивара называется mapView.)

В результате этого @synthesize заявления аналогично, если вы добавили этот код самостоятельно:

-(MKMapView *)mapView 
{ 
    return mapView1; 
} 

-(void)setMapView:(MKMapView *)newMapView 
{ 
    if (newMapView != mapView1) 
    { 
    [mapView1 release]; 
    mapView1 = [newMapView retain]; 
    } 
} 

Если вы добавляете этот код в класс самостоятельно, вы можете заменить @synthesize заявление с

@dynamic mapView;

Главное, чтобы иметь очень четкое концептуальное различие между иварами и свойствами. Это действительно две совершенно разные концепции.

+6

отличное объяснение! – ennuikiller

+1

+1 для более сильного ответа. –

+0

хорошо объясненный ответ, спасибо! –

5

Согласно документации на яблоко @Synthesize используется только для переименования переменных экземпляра. Например

@property NSString *str; 

@synthesize str = str2; 

Теперь в классе, вы не можете использовать _str как выше линии имеет переименовывает переменную экземпляра в str2

@property позволяет объектам, которые будут использоваться объекты других классов, или другими словами, делает объект публичный.

+3

Очевидно, начиная с Xcode 4.4 Clang обеспечивает поддержку автосинтеза объявленных свойств. Таким образом, @synthesize больше не требуется для большинства случаев. См. Http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html – huyz

7

Как только я столкнулся с этой проблемой при редактировании устаревшего кода, я хочу сделать дополнительные примечания к существующим ответам, о которых нужно знать.

Даже с более новой версией компилятора иногда бывает некорректно, если вы опускаете @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 больше не будут обращаться к тем же переменным. Если вы не ожидаете такого поведения, как я, это может вызвать у вас головную боль, чтобы узнать.

+0

«синхронизировать»! = «Синтезировать»? – jameshfisher

+0

Да, это две разные концепции. '@ synchronize' является директивой о том, как синхронизировать потоки при доступе к свойству, а' @ synhesize' - привязывать свойство к переменной экземпляра через getters и seters. –

+1

Комментарий jameshfisher должен был предупредить вас о том, что вы путаете синхронизацию и синтезируете в своем ответе. Вы используете эти два взаимозаменяемых. – Maple

Смежные вопросы