代码之家  ›  专栏  ›  技术社区  ›  Dave DeLong

在init和dealloc方法中有效使用访问器?

  •  24
  • Dave DeLong  · 技术社区  · 15 年前

    我现在从几个来源(stackoverflow.com、cocoa dev、文档、博客等)听说在in it和dealloc方法中使用访问器和设置(foo、setfoo:)是“错误的”。我知道如果你这样做的话,很可能会混淆其他观察该属性的对象。(给出了一个简单的例子 here )

    但是,我不得不说,我不同意这种做法,原因如下:

    新的Objective-C运行时(iPhone上的运行时和10.5中的64位运行时)允许您声明属性 没有 声明相应的ivar。例如,下面的类将在10.5或iPhone(设备,而不是模拟器)上编译得很好:

    @interface Foo : NSObject { }
    
      @property (retain) id someObject;
    
    @end
    
    @implementation Foo
    
      @synthesize someObject;
    
    @end
    

    了解到上述是一个完全有效的Objective-C类,假设我决定编写一个初始值设定项,并且为了内存管理的目的,编写一个dealoc方法(因为gc在iPhone上不可用)。我读过的关于初始值设定项和释放的所有内容都会导致我编写以下两个方法:

    - (id) init {
      if (self = [super init]) {
        //initialize the value of someObject to nil
        [self setSomeObject:nil];
      }
      return self;
    }
    
    - (void) dealloc {
      //setting someObject to nil will release the previous value
      [self setSomeObject:nil];
      [super dealloc];
    }
    

    然而,根据文献资料和民意,这是“错误的”。所以我的问题是:

    1. 我应该如何在不使用访问器的情况下初始化某个对象?您可能会说编译器(或运行时之类的)将确保某个对象已经设置为nil,但我相信依赖它是不适当的行为。在C中有一个不错的背景,我已经看到了相当多的bug,因为没有正确地初始化变量,这似乎没有什么不同。
    2. 如果我不应该在dealloc方法中使用访问器,我如何释放某个对象?

    如果其中一个的答案是“你不能”,那么在in it和dealloc方法中使用访问器有什么不好的?

    2 回复  |  直到 12 年前
        1
  •  8
  •   BJ Homer    12 年前

    我知道苹果公司认为当前10.5的行为,在这种行为下合成的IVAR是不可直接访问的;你应该能够直接访问它,但不能。

    因此,您应该能够做到:

    someObject = nil;
    

    而不是

    self.someObject = nil;
    

    同时,直接使用访问器是在不提供显式的ivar的情况下进行访问的唯一方法。

    更新 :此错误已修复;现在可以执行此操作。 someObject = nil 很好。

        2
  •  9
  •   Rob Napier    12 年前

    编辑(2013年2月13日): 正如我在下面的评论中提到的,特别是自从添加了ARC之后,我已经改变了主意。在ARC之前,我看到很多崩溃导致错误,因为在 init .IMO,尤其是与初级团队合作,在 初始化 Ivar访问的常见错误超过了它。由于ARC已经消除了这些类型的错误,所以在 初始化 可能的原因更重要,因此我已经转向支持在 初始化 dealloc ,并且只在那些地方;访问器在其他任何可能的地方(显然,您不能在访问器本身内部使用访问器….)


    弧前回答

    我强烈反对那些反对 -init . 在几乎所有的情况下,这都是一个很好的使用访问器的地方,而且它节省了许多我在新的Cocoa编码人员中看到的错误,这些编码人员在分配到 -初始化 .

    -dealloc 是一个更艰难的决定。我很自然地倾向于在那里使用访问器(这样它们就可以在任何地方使用),但它可能会由于kvo而导致头痛(如果您在setter中发布更改通知,甚至还会导致nsnotifications)。也就是说,当我不在 -DELOLLC ,我认为这很有争议,苹果对此也很不一致(我们知道他们在打电话 setView: 在uiviewController中 -DELOLLC 例如)。

    在任何情况下,我都会说,访问器的使用不足导致了100倍的过度使用错误。除非有充分的理由不使用它们,否则我总是会使用它们。

    推荐文章