我见过以下代码:
//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;
//example.m
@synthesize mapView = mapView1
mapView
和mapView1
之间的关系是什么?
它是否为set
创建了get
和mapView1
方法?
答案 0 :(得分:223)
在您的示例中,mapView1
是实例变量(ivar),一段内存存储,属于example.h
和{{中定义的类的实例。 1}}。 example.m
是属性的名称。属性是可以使用点表示法读取或设置的对象的属性:mapView
。一个属性不 基于ivar,但大多数属性都是。 myObject.mapView
声明只是告诉全世界有一个名为@property
的属性。
mapView
这一行告诉编译器为@synthesize mapView = mapView1;
创建一个setter和getter,并且他们应该使用名为mapView
的ivar。如果没有mapView1
部分,编译器将假定属性和ivar具有相同的名称。 (在这种情况下,这将产生编译器错误,因为没有名为= mapView1
的ivar。)
此mapView
语句的结果与您自己添加此代码类似:
@synthesize
如果您自己将该代码添加到班级,则可以将-(MKMapView *)mapView
{
return mapView1;
}
-(void)setMapView:(MKMapView *)newMapView
{
if (newMapView != mapView1)
{
[mapView1 release];
mapView1 = [newMapView retain];
}
}
语句替换为
@synthesize
主要的是在ivars和属性之间有一个非常明确的概念区别。它们实际上是两个非常不同的概念。
答案 1 :(得分:30)
@synthesize
为变量创建一个getter和setter。
这允许您为变量指定一些属性,并且当您@synthesize
该变量的属性时,您将为变量生成getter和setter。
属性名称可以与变量名称相同。有时人们希望它不同,以便在init
或dealloc
中使用它,或者当参数以相同的变量名称传递时。
答案 2 :(得分:16)
如果你没有在@implementation块中提供它们,你可以使用@synthesize关键字告诉编译器它应该合成属性的setter和/或getter方法。
答案 3 :(得分:8)
由于我在编辑遗留代码时遇到了这个问题,我想对现有答案做出额外的注释,需要注意。
即使使用较新的编译器版本,如果省略@synthesize propertyName
或,有时也会产生影响。
如果您在合成时声明了一个没有下划线的实例变量,例如:
标题强>
@interface SomeClass : NSObject {
int someInt;
}
@property int someInt;
@end
<强>实施强>
@implementation SomeClass
@synthesize someInt;
@end
self.someInt
将访问与someInt
相同的变量。不使用ivars的前导下划线不遵循命名约定,但我刚刚遇到必须阅读和修改此类代码的情况。
但是如果你现在认为“嘿,@ sinntize不再重要,因为我们使用更新的编译器”你错了!你的班级将导致两个ivars ,即someInt
加上自动生成的_someInt
变量。因此,self.someInt
和someInt
将不再处理相同的变量。如果你不希望我这样做,这可能会让你头疼不已。
答案 4 :(得分:6)
根据苹果文档@Synthesize仅用于重命名实例变量。例如
@property NSString *str;
@synthesize str = str2;
现在在课堂上你不能使用_str
,因为上面的行已经将实例变量重命名为str2
@property
允许对象被其他类中的对象使用,换句话说,使对象公开。
答案 5 :(得分:5)
在@interface中创建属性时,该属性将由名为_propertyName的实例变量自动返回。 因此,当您创建名为firstName的属性时,场景编译器后面将默认创建名为_firstName的实例变量。编译器还将为您创建getter和setter方法(即firstName,setFirstName)。
现在,当您通过@synthesize firstName合成属性时,您只是告诉编译器通过firstName重命名我的实例变量(_firstName)。如果要通过不同的名称重命名备份的实例变量,可以在合成属性名称时简单地指定不同的名称(即@synthesize firstName = myFirstName),通过这样做,您的属性由名为myFirstname的实例变量备份。 / p>
因此,简而言之,大部分时间@synthesize用于重命名您的属性备份的实例变量。
答案 6 :(得分:2)
基本上,synthesize创建一个setMapView和mapView方法,用于设置和获取mapView1
答案 7 :(得分:2)
它为您的对象创建getter和setter。您可以使用以下内容访问:
MKMapView* m = object.mapView;
或
object.mapView = someMapViewObject
mapView1是类中ivar的名称,mapView是getter / setter方法的名称。