obj c:accessor:self vs myInstance

时间:2012-09-19 02:46:29

标签: objective-c self accessor

在Apple的Objective-C编程语言中。在图18中,他们区分了使用self和实例引用设置变量。例如 myInstance.value = 10; self.value = 10; 1.这两个设置不同的属性命名值吗? 2.如果有多个具有名为value的属性的实例,那怎样才能自行工作? 他们还声称,“如果你不使用self。,你可以直接访问实例变量。”这意味着如果您使用,将不会调用访问者 myInstance.value = 10; 和KVO不会工作。这是真的? 3.使用@Property和@Synthesize(带垃圾收集),设置不同实例属性的正确方法是什么?自我参考有什么用? 一个数字例子可以帮助我。

4 个答案:

答案 0 :(得分:2)

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。,你可以直接访问实例变量。”这意味着如果使用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仅用于访问类中的属性。上面的例子。

答案 1 :(得分:1)

自我保护的最好方法是考虑它是如何实现的,作为每个方法调用的隐藏参数,所以方法 - [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工作,但有时您需要这样做,例如在初始化它们时。或者

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

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

对于非对象,您必须使用assign。

答案 2 :(得分:0)

self.property[self method];在类中严格用于引用自身。除非self,否则 不会引用其中的对象。

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

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,并使用其他变量来引用另一个类的实例。

希望这是有道理的。

答案 3 :(得分:0)

我的一个大问题是当ivar和财产有不同的名字时,如何捆绑在一起,特别是多个ivars。 我终于发现,如果属性名称与ivar的名称不匹配,则合成新的ivar。这可以通过self.propertyname(在object中)或object.propertyname(在object之外)访问,而不是声明的ivar。

要将不同的ivar和财产名称联系起来,将它们等同于中 @synthesize propertyname = ivarname。

感谢

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