在Objective C中添加成员变量

时间:2011-05-04 14:13:20

标签: objective-c

首先我要做

@property (retain) aMember;

然后在实现文件中我要做

@synthesize aMember;

然后在dealloc中,我完成了

self.aMember= nil; (or [aMember release])

这是3次写出基本相同的内容

有没有办法加快速度?

我的意思是我可以从IB拖放控件并且xcode会自动生成这些代码,为什么我不能为更正常的代码执行此操作?

4 个答案:

答案 0 :(得分:3)

当有人来自C#并管理我日常工作的语言时,我完全同意你质疑这个3步骤的过程。实际上它在MS Visual Studio中很容易在C#中创建属性,但我离题了。

即使你必须写下这3行,你仍然需要进行大量的工作。

  1. @property的声明告诉objective-c一些重要的属性(原子,非原子,保留,复制等),当你的类的用户设置属性时,如何处理你的属性。当你考虑这个时,这些属性(没有你编写任何代码)是;帮助您创建线程安全代码,处理对象的引用,这样您就不必担心它们会消失在您身上,或者复制值以便您拥有自己的对象副本。 @property也很重要,因为它在头文件中声明(通常)。这使得其他开发人员可以了解类的属性以及一些关于如何在其生命周期内处理传递到这些属性的对象的小提示。

  2. @synthesize也通过为该属性创建getter和setter来完成相当多的工作,它还可以为您处理各种内存管理。您无需担心释放旧引用并正确引用新对象。对我来说这是一个很好的功能,特别是当你不熟悉objective-c时,很容易忘记每次都要处理内存管理。 @synthesize只是为你做的,你不必自己编写所有的get和set代码。

  3. dealloc调用只是非内存管理环境中的生命。虽然它增加了额外的步骤,但我很欣赏显式内存管理在诸如电话等受限环境中所带来的好处。

  4. 所以所有3个步骤都是必需的,是不同的,当你想到它实际上为你做了很多工作。

答案 1 :(得分:2)

不幸的是,就是这样(现在)。 Apple最近玩弄了允许Clang隐式合成你的属性,这会把你的工作减少到:

@interface Blah : NSObject
@property (retain) Blorg *blorg;
@end

@implementation Blah

- (void)dealloc {
  [blorg release];
  [super dealloc];
}

@end

当您不希望合成实例变量时,您只需在您的实现中明确放置@dynamic blorg。但是由于一些无法预见的并发症,这个功能被删除了,尽管开发人员大多都是积极的反应。

所以,我认为可以预期苹果公司仍在努力解决这个问题。但是现在,你确实需要明确合成。

其他几点说明:

  1. 如果您正在使用垃圾收集,则无需实施-dealloc:只需确保在-finalize中进行最后一分钟的清理(例如通知取消注册)。< / p>

  2. 您还可以通过将实例变量包装在C ++类中来避免-dealloc位,该类在构造和销毁期间执行内存管理:@property prop_wrapper<Blorg> blorg;可行。然后,当您的对象被销毁时,将在您的对象上调用~prop_wrapper()。我已经完成了这项工作,并且它有效,但我建议不要这样做,因为它与KVO和KVC不相称。

  3. 您可以遍历对象的属性,并释放那些使用copyretain进行注释的对象。然后,在-dealloc中,您会有[self releaseProperties]之类的内容。我也做过这个,但我也建议不要这样做,因为如果你不小心的话,它可能会导致细微的问题,可能导致无法解释的崩溃。

答案 2 :(得分:1)

要在objective-c中实际添加成员变量,您不需要执行任何操作。

您在这3个步骤中所做的是:

  1. 声明成员变量的属性。 (在您的情况下,您指示您希望属性设置器“保留”它将成员变量设置为的对象)

  2. 以属性的默认方式声明属性getter和setter。

  3. 释放您的媒体所保留的对象。

  4. 如果您只想声明一个成员变量,那么您所要做的只是在您的类中声明它:

    @interface SomeClassObject : NSObject {
       int someMemberVariable;
    }
    @end
    

答案 3 :(得分:1)

  

这是3次写出基本相同的内容

不,不是。

@property (retain) aMember;

上面的行声明了一个属性,以便编译器知道可以将消息-aMember-setAMember:发送到您的类的对象。它还告诉编译器(和开发人员)该属性是一个retain属性(即你设置属性的对象将被保留),它是读/写的,它是原子的。

@synthesize aMember;

上面一行告诉编译器它应该自动为声明的属性生成setter和getter方法。你可以把它留下来但是你必须自己编写setter和getter。

[aMember release]; // in dealloc

是否要告诉运行时当对象被释放时,它不再需要保存对该实例变量的引用。这是必要的,因为当您使用引用计数而不是垃圾回收时,运行时不会自动清除不需要的对象。

这些行中的每一行都有不同的含义。所以你不是三次做同样的事情。