【问题标题】:Objective C: retain vs alloc - revisited目标 C:retain vs alloc - 重温
【发布时间】:2023-11-01 09:22:02
【问题描述】:

我想知道分配一个具有保留属性的对象,例如:

RootViewController *viewController;

@property (nonatomic, retain) RootViewController *viewController;


@implementation ...

viewController = [[RootViewController alloc] init];

因为这样做是不对的:

self.viewController = [[RootViewController alloc] init];

因为这会将对象保留计数增加 2,并且您将不得不释放您的对象两次,其中一个在 dealloc 方法中。

如果我正在分配我的对象,那么使用分配属性会更好吗?或者何时需要保留我使用 alloc 方法分配的对象。

我对这个问题很困惑,所以请你举例说明这种情况是如何有效的。

提前非常感谢,我将不胜感激。

问候,

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    当您将对象传递到您希望控制它的其他地方时,autoreleaseit 是标准做法:

    self.viewController = [[[RootViewController alloc] init] autorelease];
    

    或者你可以在设置变量后自己release它:

    RootViewController *controller=[[RootViewController alloc] init];
    self.viewController = controller;
    [controller release];
    

    您的第一个示例不一定是不好的做法,尽管肯定有程序员相信它。这在很大程度上取决于上下文。

    在这种情况下使用assign 可能是错误的。

    【讨论】:

    • 好答案。 assign 是完全错误的。值得注意的是,如果稍后通过 self.viewController = someOther; 重置该值,那么如果属性为 assignthat 将不是所有权转让。
    • 感谢您的回答。但是为什么使用 assign 会是错误的呢?什么时候应该使用assign??
    • @bbum,这确实解释了很多。非常感谢您的评论!!
    【解决方案2】:

    分配将是错误的。 'retain' 属性意味着您的对象拥有 viewController 的所有权。可以像在初始化程序中那样分配它,但是如果将 viewController 设置为不同的对象,则 'retain' 属性决定了创建对象后会发生什么。

    对于保留属性,生成的 setter 将如下所示:

    - (void)setViewController: (UIViewController*)value
    {
        if (viewController != value) {
            [viewController release];
        }
        viewController = [value retain];
    }
    

    【讨论】:

      【解决方案3】:

      如果您将属性设置为保留,则使用自动释放将适合如下:

      self.viewController = [[[RootViewController alloc] init] autorelease];
      

      确保使用“self”。上面以确保您使用合成的设置器,它将处理保留周围的细节。

      【讨论】:

        【解决方案4】:

        不,您应该做的是自动释放您的 RootViewController,或者在上述情况下直接分配给 ivar,您从一开始就拥有该对象的所有权。

        【讨论】:

        • 感谢您的回答,但我并没有真正理解您从一开始就获得该对象的所有权的意思??