2010-08-18 51 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

相關問題