2010-08-18 83 views
1

我是新的客观的C.我试图理解和解决Stephen Kochan在Objective C 2.0中编程的问题。这个问题来自第8章。为什么我不能直接分配变量值?

我不明白的是:为什么我不能直接分配变量值,当我可以得到它们。

例如:

这不会给我一个错误或警告。但它也没有设置X的值和Y

go.origin.x = 300; 
go.origin.y = 100; 

但是,这工作得很好,给我想要的结果:

NSLog (@"print %i, %i", go.origin.x, go.origin.y); 

这里是我的XYPoint.h

#import <Foundation/Foundation.h> 

@interface XYPoint : NSObject { 

    int _x; 
    int _y; 

} 
@property int x; 
@property int y; 

@end 

XYPoint.m

#import "XYPoint.h" 

@implementation XYPoint 

@synthesize x = _x; 
@synthesize y = _y; 
@end 

中把握hicObject.h

#import <Foundation/Foundation.h> 
#import "XYPoint.h" 

@interface GraphicObject : NSObject { 

    XYPoint *_origin; 
} 

@property (nonatomic, retain) XYPoint *origin; 

-(void) setOrigin : (XYPoint *) pt; 

@end 

GraphicObject.m

#import "GraphicObject.h" 

@implementation GraphicObject 

@synthesize origin = _origin; 

-(void) setOrigin : (XYPoint *) pt { 

    _origin = [[XYPoint alloc] init]; 

    _origin = pt; 

    //_origin.x = pt.x; 
    //_origin.y = pt.y; 

} 

@end 

此外,如果不想让我的origin.x和origin.y改变,当我改变我的Xypoint x和y,为什么我有要做到这一点:

_origin.x = pt.x; 
_origin.y = pt.y; 

,为什么不只是:

_origin = pt; 

例如在主要文件:

XYPoint *myPoint = [[XYPoint alloc] init]; 
go.origin = myPoint; 

myPoint.x = 250; 
myPoint.y = 50; 

NSLog(@"Origin values %i, %i", go.origin.x, go.origin.y); 

myPoint.x = 100; 
myPoint.y = 10; 

NSLog(@"Origin values %i, %i", go.origin.x, go.origin.y); 

我明白起源的值不会改变。但是,我必须在setOrigin:方法,这样分配的:

_origin.x = pt.x 

,而不是像这样:

_origin = pt; 

谢谢大家。我知道这是一个很长的问题。我真的很想明白,也看过很多地方,但我甚至不知道要搜索什么。你称这种任务是什么?

回答

3

恭喜!你已经发现Objective-C的属性是句法糖围绕着一个getter方法和一个setter方法。由于属性并不是真正的对象字段(因为xyCGPoint结构的字段),修改对象属性的字段不会执行任何操作 - 代码将被解析为“获取属性的值,然后修改该值的结果副本。“

现在,你可以属性获取和设置(如anObject.widget.gear.speed *= 2),你可以领域获取并设置(如myStructure.owner.uniqueID = rand()),正如你所看到的,他们看起来几乎是相同的。但你可以“T混合和匹配。

为什么?

嗯,因为......你不能,而这几乎是它。因此,在未来,如果你有这些各种各样的问题,检查是否混合并匹配属性和字段。如果是这样,您必须将其分开:

CGPoint pt = go.origin; 
pt.x += 300; 
pt.y -= 100; 
go.origin = pt; 
+0

感谢您的清除。在你解释之前,我很难理解这一点。也可以清除我对分配_origin.x = pt.x而不是_origin = pt的第二个疑问。再次感谢。 – Dives 2010-08-19 18:23:31

+0

您可以直接将结构的值分配给同一类型的另一个结构,所以'_origin = pt'如果它们是结构就可以工作。但是,因为您创建了一个模仿CGPoint结构的类,所以像这样的赋值是通过引用*赋值*,而不是*赋值*。所以你说“make'_origin'和'pt'指的是同一个对象,但是原来的引用在'go'中保持不变。 – 2010-08-19 18:34:38

+0

是的,它可以工作,但如上面的例子,当我更改myPoint.x或myPoint.y时,_origin.x和_origin.y的值也会改变。但是当我声明_origin.x = pt.x和_origin.y = pt.y.即使我改变myPoint,_origin的值也不会改变。 – Dives 2010-08-19 18:39:08

0
@property int x; 
@property int y; 

...应该是...

@property (nonatomic, readwrite) int x; 
@property (nonatomic, readwrite) int y; 
+0

这是一个iPhone问题。你应该用'CGRect'和'CGRectMake'替换'NSRect'和'NSMakeRect'# – Jasarien 2010-08-19 00:45:37

+0

是的,你说得对,我最近在桌面上工作太多,忘记了iPhone的微妙之处。但我也发现了OP的错误原因。我真的不应该匆忙回答这个问题。 – 2010-08-19 00:55:09

+0

以上声明不起作用。此外,Jasarien,我是新的目标C,所以纠正我,如果我错了,但我没有使用NSRect和NSMakeRect。 你还可以看看我的其他问题。谢谢 – Dives 2010-08-19 03:14:15

相关问题