使用@property和@synthesize对ivar进行隐式创建



好,所以最近我有了这个可能的坏习惯,用@property声明我的类属性,用@synthesize创建getter和setter,然后在任何我需要它们的地方使用它们作为self.name,而不需要引用内部变量(让@synthesize做它的工作)

现在,当然,这不允许我访问内部变量(例如:name_),但从我编码到目前为止,我并不是真的需要它。对于只读属性,我不使用@synthesize,而是自己实现getter。

一切看起来都很好,但不知怎么的,我有一种感觉,这是不对的,因为我看过的所有开源库,也声明了ivar,并在整个代码中使用它。@property + @synthesize,没有ivar,这绝对是懒惰的选择,但缺点是什么?有人能给我一些建议吗?

此外,我已经读到,作为一般建议,它是可以在任何地方使用self.propertyName在你的类代码除了deallocinit方法。但只要你确保对象是初始化的:

-(id) init
{
    if( (self=[super init] )) {
    }
    return self;
}

和在调用[super dealloc]之前删除所有键值观察者,一切都应该没问题。对吧?

@synthesize将创建与属性同名的内部变量:

@synthesize name;
- (void) dealloc {
   [name release], name  = nil;
   [super dealloc]
}

或者给内部变量另起一个名字:

@synthesize name = _name;
- (void) dealloc {
   [_name release], _name  = nil;
   [super dealloc]
}

我在init中使用self.name,但不在dealloc中使用,似乎工作得很好。

这取决于你为哪个版本的Objective-c运行时构建:现代或遗留。

  • 现代版本支持"声明属性的实例变量合成"。ie。您不需要为每个@property定义实例变量。运行时将负责为您创建一个。默认情况下,ivar将与@property命名相同。您可以使用@synthesize propertyName = iVarName;

  • 格式更改ivar名称
  • 遗留版本不支持ivar合成,因此您必须为@property的存储定义一个ivar。

Mac OS X v10.5及更高版本的iPhone应用程序和64位程序使用最新版本的运行时。您应该假设所有其他平台都使用遗留版本。

缺点是什么?嗯,最大的一个是可移植性——通过不定义你的代码可以在更少的平台上运行的变量,例如它不能在OSX 10.4上运行。你也会失去一些控制/灵活性& &;可能会无意中与sub- &超级类。

重要的是要记住,您应该释放使用@synthesize合成的属性。属性不会自动释放-你应该release任何合成属性没有标记为assign(不要释放任何标记为assign的属性)。

注意:为了获得额外的学分,你可以整理你的只读属性。没有什么理由编写自己的访问器而不使用@synthesize。只需将属性定义为只读&可选地命名getter @property(getter=isIntReadOnlyGetter, readonly)

最新更新