【问题标题】:Best practice on using @property ivars使用@property ivars 的最佳实践
【发布时间】:2012-10-05 19:37:15
【问题描述】:

有人可以分享一些关于在初始化方法或指定初始化程序中使用@property iVars 的最佳实践/代码约定的知识吗?

请看我的例子:

@interface MyClass ()
@property(nonatomic,strong) nsstring *tempString;
@property(nonatomic,strong) NSMutableArray *arrItems;
@end

@implementation ViewController

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

        //Is this best practice / correct
        _tempString = @"";
        _arrItems = [[NSMutableArray alloc] initWithCapacity:0];
        ...
        ...

        //Or this
        self.tempString = @"";
        self.arrItems = [[NSMutableArray alloc] initWithCapacity:0];
    }
    return self;
}

@end

关于为什么应该使用其中一个或另一个的任何建议?

谢谢...

【问题讨论】:

  • 在您的示例中,我通常会使用属性设置器分配一个值,例如self.tempString = @"Some Value";。原因是您可能在 setter 中有一些自定义逻辑。例如,也许您的 tempString 设置器想要从电话号码中删除破折号。如果您将值直接分配给 ivar,您将绕过该逻辑。这个想法是,如果你有一个 setter,就使用 setter,除非你看到不这样做的理由。请注意,如果您直接分配给 ivars,您将需要自己管理保留/复制/原子结构(除非被覆盖,否则设置器会处理此问题)。

标签: ios objective-c-2.0


【解决方案1】:

Apple 对此主题的指导包含在恰当命名的部分Don’t Use Accessor Methods in Initializer Methods and dealloc

【讨论】:

    【解决方案2】:

    阅读此主题:Why shouldn't I use Objective C 2.0 accessors in init/dealloc?

    换句话说,如果您不打算使用 KVO,您可以使用第二种方法:

    //Or this
            self.tempString = @"";
            self.arrItems = [[NSMutableArray alloc] initWithCapacity:0];
    

    但要小心使用 alloc-init,不要忘记自动释放。

    【讨论】:

    • 从他的代码示例中strong的存在来看,他一定是使用ARC,所以autorelease不适用。
    • 感谢您的回复,如果我直接分配给 _tempString 我不需要在 ARC 下保留/复制,我说对了吗?
    【解决方案3】:

    通常最好在定义时使用属性表示法,部分(大部分?)出于 Jeremy 提到的原因。

    当您可以在方法设置器覆盖中设置断点并将其应用于修改变量的所有代码路径时,调试特定变量会容易得多。

    另一个原因是保持一致的内存管理模型,尽管它不太重要,因为您使用的是 ARC。但是,如果您不是,并且强保留,那么您将确保您设置到该属性的对象在您设置该属性的任何地方都会自动释放,并且如果您直接设置该属性,则不必处理释放当前值变量。

    无论您使用什么实践,一致性对于维护/可读性和调试都很重要。

    【讨论】:

      【解决方案4】:

      我更喜欢属性的惰性实例化方法。

      @synthesize 之后,您可以覆盖您的 getter 以延迟实例化您的属性

      例如:

      -(NSString *)tempString {
      
          if(!tempString) {
              _tempString = @"";
          }
          return _tempString;
      }
      

      -(NSMutableArray *)arrItems {
      
          if(!_arrItems) {
              _arrItems = [[NSMutableArray alloc] initWithCapacity:0];
          }
          return _arrItems;
      }
      

      如果您确实想在init 方法中设置您的属性,请使用点符号self.myProperty,以便它使用为属性定义的setter,而不是直接使用私有类方法。

      【讨论】:

        【解决方案5】:

        根据 Apple 的规定,您应该init...dealloc 方法中使用访问器:

        您应该始终直接从内部访问实例变量 初始化方法,因为在设置属性时, 对象的其余部分可能尚未完全初始化。即使你 不要提供自定义访问器方法或知道任何副作用 在你自己的类中,未来的子类很可能会覆盖 行为。

        取自此文档:Encapsulating Data

        【讨论】:

          猜你喜欢
          • 2010-10-24
          • 1970-01-01
          • 1970-01-01
          • 2012-12-31
          • 1970-01-01
          • 2017-11-29
          • 2010-10-08
          • 2012-04-11
          • 2010-12-04
          相关资源
          最近更新 更多