@synthesize究竟做了什么?

Hoa*_*Nam 147 iphone objective-c

我见过以下代码:

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

//example.m
@synthesize mapView = mapView1
Run Code Online (Sandbox Code Playgroud)

问题:mapViewmapView1之间有什么关系?它是否为mapView1创建了setget方法?

谢谢 !

Fel*_*xyz 227

在您的示例中,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];
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您自己将该代码添加到类中,则可以用该@synthesize语句替换该语句

@dynamic mapView;

主要的是在ivars和属性之间有一个非常明确的概念区别.它们实际上是两个非常不同的概念.


vod*_*ang 31

@synthesize 为变量创建一个getter和setter.

这允许您为变量指定一些属性,当您@synthesize将该属性添加到变量时,您将为变量生成getter和setter.

属性名称可以与变量名称相同.有时,人们希望它是不同的,所以在使用它initdealloc或当参数使用同一个变量的名称传递.


Dav*_*ong 16

文档:

如果不在@implementation块中提供它们,则使用@synthesize关键字告诉编译器它应该为该属性合成setter和/或getter方法.


Lar*_*erg 8

因为我在编辑遗留代码时遇到这个问题,我想要对现有答案做出额外的注释,我们需要注意.

即使使用较新的编译器版本,如果省略@synthesize propertyName或不省略,它有时也会产生影响.

如果您在仍然合成它的情况下声明一个没有下划线的实例变量,例如:

标题:

@interface SomeClass : NSObject {
   int someInt;
}
@property int someInt;
@end
Run Code Online (Sandbox Code Playgroud)

执行:

@implementation SomeClass
@synthesize someInt;
@end
Run Code Online (Sandbox Code Playgroud)

self.someInt将访问相同的变量someInt.不使用ivars的前导下划线不遵循命名约定,但我只是遇到了必须阅读和修改此类代码的情况.

但是如果你现在想"嘿,@ sinnthesize不再重要,因为我们使用更新的编译器"你错了!然后你的班级将产生两个ivars,即someInt加上一个自动生成的_someInt变量.因此self.someInt,someInt不再解决相同的变量.如果您不希望我这样做,这可能会让您头疼不已.


小智 7

根据苹果文档,@ Synthesize仅用于重命名实例变量.例如

@property NSString *str;

@synthesize str = str2; 
Run Code Online (Sandbox Code Playgroud)

现在在类中你无法使用,_str因为上面的行已经将实例变量重命名为str2

@property 允许对象被其他类中的对象使用,或者换言之,使对象公开.

  • 显然,从Xcode 4.4开始,Clang为声明属性的自动合成提供支持.因此,大多数情况下不再需要@synthesize.请参阅http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html (3认同)

Mah*_*ale 5

在@interface中创建属性时,该属性将由名为_propertyName的实例变量自动返回。因此,当您创建一个名为firstName的属性时,默认情况下,后台编译器将创建一个名为_firstName的实例变量。编译器还将为您创建getter和setter方法(即firstName,setFirstName)。

现在,当您通过@synthesize firstName合成属性时,您只是在告诉编译器通过firstName重命名我的实例变量(_firstName)。如果要使用其他名称重命名备份的实例变量,则可以在合成属性名称时(即@synthesize firstName = myFirstName)简单地分配其他名称,这样做可以通过名为myFirstname的实例变量来备份属性。

简而言之,大多数情况下@synthesize用来重命名由属性备份的实例变量。