繁体   English   中英

@synthesize 到底是做什么的?

[英]What exactly does @synthesize do?

我看到了下面的一段代码:

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

//example.m
@synthesize mapView = mapView1

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

在您的示例中, mapView1是一个实例变量(ivar),这是一块内存存储,属于example.hexample.m定义的类的实例。 mapView属性的名称。 属性是可以使用点表示法读取或设置的对象的属性: myObject.mapView 一个属性不必是基于伊娃,但大多数属性。 @property声明只是告诉全世界有一个名为mapView的属性。

@synthesize mapView = mapView1;

这一行告诉编译器为mapView创建一个 setter 和 getter,并且他们应该使用名为mapView1的 ivar。 如果没有= mapView1部分,编译器将假定属性和 ivar 具有相同的名称。 (在这种情况下,这会产生编译器错误,因为没有名为mapView ivar。)

这个@synthesize语句的结果类似于如果你自己添加了这个代码:

-(MKMapView *)mapView
{
   return mapView1;
}

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

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

@dynamic mapView;

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

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

这使您可以为变量指定一些属性,并且当您将该属性@synthesize到变量时,您将为变量生成 getter 和 setter。

属性名称可以与变量名称相同。 有时人们希望它是不同的,以便在initdealloc使用它,或者在使用相同变量名传递参数时使用它。

文档

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

当我在编辑遗留代码时遇到这个问题时,我想对需要注意的现有答案做额外的说明。

即使使用较新的编译器版本,如果省略@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.someIntsomeInt将不再处理相同的变量。 如果你不期望像我那样的行为,这可能会让你头疼。

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

@property NSString *str;

@synthesize str = str2; 

现在在类中您不能使用_str因为上面的行已将实例变量重命名为str2

@property允许对象被其他类中的对象使用,或者换句话说,使对象成为公共对象。

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

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

因此,简而言之,@synthesize 大部分时间用于重命名由您的属性支持的实例变量。

查看苹果文档

基本上合成创建了一个 setMapView 和 mapView 方法,它们设置和获取 mapView1

它为您的对象创建 getter 和 setter。 您可以使用以下内容访问:

MKMapView* m = object.mapView;

或者

object.mapView = someMapViewObject

mapView1 是类中 ivar 的名称,mapView 是 getter/setter 方法的名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM