【问题标题】:obj c: accessor: self vs myInstanceobj c:访问器:self vs myInstance
【发布时间】:2012-09-19 02:46:28
【问题描述】:

在 Apple 的 The Objective-C Programming Language 中 p。 18,他们区分了使用 self 与实例引用设置变量。例如 myInstance.value = 10; 自我价值=10; 1.这两个会设置不同的属性命名值吗? 2. 如果有多个实例具有名为 value 的属性,self 如何工作? 他们还断言,“如果你不使用 self.,你可以直接访问实例变量。”这意味着如果您使用访问器将不会被调用 myInstance.value = 10; 并且 KVO 不起作用。这是真的? 3. 使用@Property 和@Synthesize(带有垃圾回收),设置不同实例属性的正确方法是什么?自我参考有什么用? 请举一个数字示例对我有帮助。

【问题讨论】:

    标签: objective-c self accessor


    【解决方案1】:

    1 - 这两个会设置不同的名为 value 的属性吗?

    不,我认为您误解了 the guide 在区分 self.value 和 myInstance.value 时所说的内容。在这两种情况下,都会调用 setter 函数(即 setValue:)。

    您使用 self 访问您自己的属性(即,从您编写的类的函数中引用属性)。喜欢:

    @interface MyObject : NSObject
    @property( nonatomic ) NSInteger value;
    - (void) doSomething;
    @end
    
    
    @implementation MyObject
    
    @synthesize value;
    
    - (void) doSomething
    {
        self.value = 10;
    }
    
    @end
    

    而您将使用 myInstance 从该类之外的某个其他变量中设置属性。

    MyObject* anObject = [[MyObject alloc] init];
    anObject.value = 10;
    

    2 - 如果有多个实例具有名为 value 的属性,self 如何工作?

    不会的。往上看。

    他们还断言,“如果不使用 self.,则直接访问实例变量。”这意味着如果您使用 myInstance.value =10; 则不会调用访问器并且 KVO 不起作用。这是真的吗?

    没有。 self.value 和 myInstance.value 都调用它们的访问器(setValue: 在这种情况下),并且 KVO 将工作。该断言的意思是,如果您从自己的类中访问 ivar,而不使用访问器,KVO 将无法工作。

    @interface MyObject : NSObject
    @property( nonatomic ) NSInteger value;
    - (void) doSomething;
    @end
    
    
    @implementation MyObject
    
    @synthesize value;
    
    - (void) doSomething
    {
        self.value = 10;    // This invokes the accessor, and KVO works.
        value = 10;  // This just sets the instance variable, and KVO won't work.
    }
    
    @end
    

    使用@Property 和@Synthesize(带有垃圾回收),设置不同实例属性的正确方法是什么?自我参考有什么用?请举一个数字示例对我有帮助。

    如上所示,使用实例名称。 self 仅用于访问类中的属性。上面的例子。

    【讨论】:

    • 谢谢大家,我想我理解只有一个 ivar 和一个属性,但不是当有两个 ivar,每个 ivar 都有一个同名的属性。
    • (我希望我在这里正确使用了格式。)谢谢大家,我想我理解只有一个 ivar 有一个属性,但不是当有两个 ivar,每个都有一个属性具有相同的名称。示例:ivars coin1,coin2; @适当的价值;。在 MYObject 中,我不能说 coin1.value = 5; coin2.value = 10;.那么如何使用访问器设置值?设置另一个对象并从那里进行设置似乎很荒谬。
    【解决方案2】:

    理解 self 的最好方法是考虑它是如何实现的,作为每个方法调用的隐藏参数,因此方法 -[UIView drawRect:] 具有类似的 c 函数实现

    BOOL drawRect:( UIView * self, SEL _cmd, NSRect r ) { };    // of cause : is not legal in c
    

    和调用方法有点像(忽略动态查找)

    UIView  * v = ...
    NSRect  r = ...
    
    drawRect:( v, @selector(drawRect:), r );
    

    因此,如果您在 drawRect: 实现中调用一个属性,那么您正在为名为 self 的隐藏对象参数执行此操作。

    直接访问实例变量会阻止 KVO 工作,但有时您希望这样做,例如在初始化它们时。

    如果您说垃圾收集时是指自动引用计数,则大多数情况下您希望它们是强对象或复制对象,使用复制的不可变字符串将变成保留,如果它是可变的,那么您通常需要一个复制以防止在您下方更改原件。

    strong 的一个潜在问题是,您最终可能会遇到循环引用,如果您按照周围的链接返回到原始对象,那么每个对象都会间接保留自己,并且您会遇到一个 catch-22 情况,即该对象必须在它可以释放自己之前释放自己。所以在这些情况下你需要使用weak。您通常可以通过考虑概念上哪个对象拥有另一个对象来确定谁应该保留和谁应该弱。

    对于非对象你必须使用assign。

    【讨论】:

      【解决方案3】:

      self.property[self method]; 在类中严格使用来引用自身。除了self之外,您永远都不会在其内部引用对象。

      相反,使用对象的实例来引用另一个类的对象。例如,我会以如下方式从我的viewController 中引用UIImageView

      UIImageView* imgView = [[UIImageView alloc] init];
      [imgView setFrame:CGRectMake(0,0,320,480)];
      

      但是,如果我正在编辑我调用的 UIImageView 的子类,比如 rotateImageView:

      @implementation rotatingImageView
      
      -(id)init
      {
          //Super instantiation code that I don't remember at the moment goes here
          [self setFrame:CGRectMake(0,0,320,480)];
      }
      

      这只是一个方法的例子。

      再一次,您在自己的类中严格使用 self,并使用其他变量来引用另一个类的实例。

      希望这是有道理的。

      【讨论】:

      • 我仍然缺少一些东西:如果有两个或多个具有相同命名属性(例如 value)的对象实例,self.value 怎么知道要使用哪一个?
      【解决方案4】:

      我的大问题是,当 ivar 和属性具有不同名称时,如何将它们绑定在一起,尤其是多个 ivar。
      我终于发现,如果属性名称与 ivar 的名称不匹配,则会合成一个新的 ivar。这是由 self.propertyname(对象内)或 object.propertyname(对象外)访问的,而不是声明的 ivar。

      要将不同名称的 ivar 和属性联系起来,请将它们等同于 in
      @synthesize 属性名 = ivarname。

      感谢

      http://blog.ablepear.com/2010/05/objective-c-tuesdays-synthesizing.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-17
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        • 1970-01-01
        • 1970-01-01
        • 2013-09-12
        相关资源
        最近更新 更多