【问题标题】:When should I use the “self” keyword?什么时候应该使用“self”关键字?
【发布时间】:2010-11-02 17:43:58
【问题描述】:

什么时候应该在我的 iphone 开发应用程序中使用 self 表达式?假设我有 2 个字段:UITextField *text1;NSString *str1; 保留和合成。

当我访问这两个字段中的任何一个时,我应该什么时候以及什么时候不应该使用self.text1self.str1

【问题讨论】:

    标签: iphone objective-c ios self


    【解决方案1】:

    self 不是关键字,而是表达式。此外,您可以在任何时候使用它来引用自己或直接引用自己的方法或属性。 “你自己”当然是指你正在操作的类的实例。

    【讨论】:

    • 所以看起来它与 Java this 表达式相同,除非处理具有相同名称的变量,否则并不总是需要它
    • 一个重要的区别是self.str1 = @"abc" 将使用访问器方法 (setStr1:) 而str1 = @"abc" 不会。当使用带有retain 属性的属性时,这种区别很关键。所以,它真的不是“与 Java this 相同”。
    【解决方案2】:

    在某些情况下,通常不鼓励使用self.-表达式来访问属性。 通常你 总是 使用 self 属性。 这是最安全和最简单的方式。特别是如果你使用了retain,那么内存管理将为你完成。

    这条规则的两个例外:

    • 任何init 方法。
    • dealloc

    在这两种情况下,您都在处理 部分初始化 对象。在此处使用 setter 或 getter 时可能会出现一些副作用——因为它们是方法,因此可能会被覆盖。

    例如,获取一个类A,其属性foo 已被类B 子类化。子类B 添加了一个属性bar 并覆盖了foo 的setter。现在您的init 方法调用setFoo:,因为您使用了带有一些初始值的self.foo = ...。但是,子类也访问此 setter 中 bar 的值。但在这种情况下,可能会发生 bar 从未初始化并指向一些任意数据的情况。 在 init 中调用 setter 会导致崩溃,尽管在​​您自己的代码中概率可能不会太高。

    【讨论】:

      【解决方案3】:

      在您的示例中,当您使用 self 时,您并没有直接访问实例变量,而是访问了您定义的属性。

      考虑这个例子:

      @interface Foo : NSObject {
         NSString *_bar;
      }
      
      @property (nonatomic, retain) NSString *bar;
      
      @end
      
      @implementation Foo
      @synthesize bar = _bar;
      -(void)baz {
         _bar = @"ivar";  //accessing the ivar
         self.bar = @"property"; //accessing the ivar via the property
      }
      
      @end
      

      一般来说,如果您使用属性,几乎没有理由使用 ivar。这具有自动为您保留和释放价值的额外好处。

      但在其他情况下,您的属性将具有 readonly 修饰符。在这些情况下,有必要直接访问您的 ivars 以设置它们的值。

      【讨论】:

      • 我很困惑。 _foo 和 foo 在哪里声明?它们真的应该是你的 baz 方法中的 _bar 和 bar 吗?
      【解决方案4】:

      如果您有自定义 getter,有时在方法调用中使用 self 也是一个好主意。使用 Core Data 的应用程序中的 managedContext 对象就是一个很好的例子。如果您通过self.managedContext 引用它,您可以覆盖并将对象设置为它需要的对象(如果它是nil)。在创建使用 Core Data 的应用程序时,请参考 XCode 生成的代码。

      这里是XCode生成的代码示例,实际上:

      @interface YourAppDelegate : NSObject <UIApplicationDelegate>
      {
      @private
          NSManagedObjectContext *managedObjectContext_;
      }
      
      
      @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
      
      
      
      @implementation ContractionTimerAppDelegate
      
      /**
       Returns the managed object context for the application.
       If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
       */
      - (NSManagedObjectContext *)managedObjectContext {
      
          if (managedObjectContext_ != nil) {
              return managedObjectContext_;
          }
      
          NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
          if (coordinator != nil) {
              managedObjectContext_ = [[NSManagedObjectContext alloc] init];
              [managedObjectContext_ setPersistentStoreCoordinator:coordinator];
          }
          return managedObjectContext_;
      }
      
      @end
      

      【讨论】:

        【解决方案5】:

        如果你“综合”变量,你应该“自我”。变量。小经验法则

        【讨论】:

          【解决方案6】:

          我对objective-c一无所知,但这看起来很像其他语言(如C++、C#、Java、PHP等)的this关键字。如果是这样,那么我的建议是始终使用它。这样,如果您曾经(不小心)定义了同名的局部变量,您的代码就不会中断。

          但是,我还必须补充一点,这在某种程度上是一场宗教辩论,在程序员社区中有着激烈的冲突历史。因此,对这个建议持保留态度,并使用任何对你来说最有意义的东西。保持一致即可。

          【讨论】:

          • 但请注意,这不仅仅是 Objective-C 中的样式/可维护性问题——当使用具有 getter/setter 方法的属性时,省略“self”会绕过 getter/setter;存在真正的语义差异。
          • 这正是我想要的,很好
          • @David Gelhar - 抱歉。告诉你我不知道。 :P
          猜你喜欢
          • 1970-01-01
          • 2011-06-30
          • 1970-01-01
          • 2012-05-22
          • 1970-01-01
          • 2010-09-09
          • 1970-01-01
          • 2017-09-11
          相关资源
          最近更新 更多