@Synthesize tam olarak ne yapar?


148

Aşağıdaki kod parçasını gördüm:

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

//example.m
@synthesize mapView = mapView1

Arasındaki ilişki nedir mapViewve mapView1? İçin setve getyöntemi oluşturuyor mapView1mu?


1
Güncelleme: ancak en son araç seti ile @synthesize artık (neredeyse) hiçbir zaman gerekli değildir. Diğer Yığın Taşması Sorusunun cevabına bakınız .
Ali Beadle

Yanıtlar:


228

Örnekte, mapView1bir bir örneği değişken (ivar) 'de tanımlandığı sınıfının bir örneğine ait bellek depolama parçası example.hve example.m. mapViewbir mülkün adıdır . Özellikleri okumak veya nokta gösterimi kullanılarak ayarlanabilir bir nesnenin nitelikleri şunlardır: myObject.mapView. Bir mülk bir ivar'a dayalı olmak zorunda değildir , ancak çoğu mülktür. @propertyDeklarasyon basitçe adında bir özellik olduğu dünyayı anlatır mapView.

@synthesize mapView = mapView1;

Bu satır derleyiciye bir ayarlayıcı ve alıcı oluşturmasını söyler ve mapViewçağrılan ivar'ı kullanmaları gerekir mapView1. = mapView1Parça olmadan, derleyici, özellik ve ivar'ın aynı ada sahip olduğunu varsayar. (Bu durumda, derlenmiş bir hata üretilir, çünkü çağrılan bir ivar yoktur mapView.)

Bu @synthesizeifadenin sonucu, bu kodu kendiniz ekleyip eklemediğinize benzer:

-(MKMapView *)mapView
{
   return mapView1;
}

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

Bu kodu sınıfa kendiniz eklerseniz, @synthesizeifadeyi

@dynamic mapView;

Ana şey, ivarlar ve özellikler arasında çok açık bir kavramsal ayırım yapmaktır. Bunlar gerçekten çok farklı iki kavram.


31

@synthesize değişken için bir alıcı ve ayarlayıcı oluşturur.

Bu, değişkenleriniz için bazı öznitelikler belirtmenize olanak tanır ve @synthesizebu özelliği değişkene eklediğinizde , değişken için alıcı ve ayarlayıcı oluşturursunuz.

Özellik adı, değişken adıyla aynı olabilir. Bazen insanlar kullanmak üzere farklı olmak istiyorum initya deallocveya parametre aynı değişkenin adıyla geçirildiğinde.


16

Gönderen belgeler :

@ Uygulama bloğunda sağlamazsanız, derleyiciye özellik için ayarlayıcı ve / veya alıcı yöntemlerini sentezlemesi gerektiğini bildirmek için @synthesize anahtar sözcüğünü kullanırsınız.


8

Ben sadece eski kodu düzenlerken bu sorunla karşılaştığım gibi farkında olması gereken mevcut cevaplar için ek notlar yapmak istiyorum.

Daha yeni bir derleyici sürümünde bile, atlarsanız @synthesize propertyNameveya atlamazsanız bazen fark yaratır .

Halen sentezlerken alt çizgi olmadan bir örnek değişkeni bildirmeniz durumunda , örneğin:

Başlık:

@interface SomeClass : NSObject {
   int someInt;
}
@property int someInt;
@end

Uygulama:

@implementation SomeClass
@synthesize someInt;
@end

self.someIntile aynı değişkene erişecek someInt. Ivars için önde gelen bir alt çizgi kullanmamak, adlandırma kurallarına uymaz ama ben sadece bu kodu okumak ve değiştirmek zorunda kaldım bir duruma geldi.

Ama şimdi "Hey, daha yeni bir derleyici kullandığımız için @synthesize artık önemli değil" diye düşünürseniz yanılıyorsunuz! Daha sonra sınıfınız iki ivar , someIntartı otomatik olarak oluşturulmuş bir _someIntdeğişkene neden olacaktır. Böylece self.someIntve someIntbir daha aynı değişkenleri ele almayacaktır. Benim yaptığım gibi bir davranış beklemiyorsanız, bu size biraz baş ağrısı verebilir.


"synize"! = "sentez"?
jameshfisher

Evet, bunlar 2 farklı kavram. @synchronizeözelliğe erişirken iş parçacıklarının nasıl senkronize edileceğine ilişkin bir direktiftir @synthesizeve özelliği alıcılar ve ayarlayıcılar aracılığıyla bir örnek değişkenine bağlar.
Lars Blumberg

1
jameshfisher'ın yorumu, cevabınızda senkronize etmeyi ve sentezlemeyi karıştırdığınız konusunda sizi uyarmak içindir. İkisini birbirinin yerine kullanabilirsiniz.
Maple

1
Beni haberdar ettiğin için teşekkürler! Tamamen nezaret edip, mevcut olmayan @synchronize anahtar kelimesini kullanmamak için cevabı güncelledim.
Lars Blumberg

Bu durumda, konu hakkında uyarır 10 Xcode: Autosynthesized property 'someInt' will use synthesized instance variable '_someInt', not existing instance variable 'someInt'. (Bu uyarının hangi xcode sürümünün eklendiğini bilmiyorum.)
zwcloud

7

Apple belgelerine göre @Synthesize yalnızca örnek değişkenlerini yeniden adlandırmak için kullanılır. Örneğin

@property NSString *str;

@synthesize str = str2; 

Sınıfta _stryukarıdaki satırın örnek değişkenini yeniden adlandırdığı için kullanamazsınız .str2

@property nesnelerin diğer sınıflardaki nesneler tarafından kullanılmasına izin verir veya başka bir deyişle nesneyi herkese açık hale getirir.


3
Görünüşe göre, Xcode 4.4 ile başlayarak, Clang beyan edilen özelliklerin otomatik sentezi için destek sağlar. Yani çoğu durumda synthesize artık gerekli değildir. Bkz. Useyourloaf.com/blog/2012/08/01/…
huyz

5

@İnterface içinde bir özellik oluşturduğunuzda, bu özellik _propertyName adında bir örnek değişkeni tarafından otomatik olarak geri alınır. FirstName adında bir özellik oluşturduğunuzda, sahne derleyicisinin arkasında varsayılan olarak _firstName adında bir örnek değişken oluşturur. Derleyici sizin için getter ve setter yöntemini de yaratacaktır (yani firstName, setFirstName).

Şimdi özelliği @synthesize firstName ile sentezlediğinizde, derleyiciye örnek değişkenimi (_firstName) firstName ile yeniden adlandırmasını söylersiniz. Yedeklenen örnek değişkeninizi farklı bir adla yeniden adlandırmak istiyorsanız, özellik adını sentezlerken farklı bir ad atayabilirsiniz (yani, @synthesize firstName = myFirstName), bunu yaparak mülkünüz myFirstname adlı bir örnek değişkeni tarafından yedeklenir.

Kısacası, çoğu zaman @synthesize, mülkünüz tarafından yedeklenen örnek değişkeninizi yeniden adlandırmak için kullanılır.



2

Nesneniz için alıcı ve ayarlayıcı oluşturur. Bunun gibi bir şeyle erişebilirsiniz:

MKMapView* m = object.mapView;

veya

object.mapView = someMapViewObject

mapView1 sınıftaki ivar adı, mapView getter / setter yöntem (ler) inin adıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.