0

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

4

4 回答 4

2

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

不,我认为您误解了指南在区分 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 仅用于访问类中的属性。上面的例子。

于 2012-09-19T08:10:02.450 回答
1

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

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。您通常可以通过考虑概念上哪个对象拥有另一个对象来锻炼谁应该保留和谁应该弱化。

对于非对象,您必须使用分配。

于 2012-09-19T07:16:25.917 回答
0

self.property并且[self method];在类中严格使用来引用自身。你永远不会用任何东西来指代对象本身self

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

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

但是,如果我正在编辑我调用的 UIImageView 的子类,请说 rotationImageView:

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

希望这是有道理的。

于 2012-09-19T03:38:30.203 回答
0

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

要绑定 ivar 和属性的不同名称,请将它们等同于
@synthesize propertyname = ivarname。

谢谢

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

于 2012-09-21T05:47:10.233 回答