1

我在理解 Objective-C 中如何使用指针和引用时遇到了我怀疑的基本错误。我一直在研究这个问题,调整我的代码等,等等……无济于事。

我知道我在某处犯了一个简单的错误(Objective-C 的新手,但不是 OOP),但我没有看到它......啊:P

我欢迎像你们这样更聪明的人提供任何和所有的意见。:)

如果我可以说明我的问题,它会是这样的:

在我的“main.m”文件中,我实例化了某个“矩形”类的 4 个单独的实例,每个实例都具有唯一的尺寸和可通过 getter(s)/setter(s) 访问的笛卡尔坐标。“width”和“height”属性是合成的,而坐标被包装在一个对象(XYPpoint 类)中,可通过自定义方法访问。

当我访问宽度和高度属性时,我能够为任何和所有实例获取/设置唯一值,但是当我尝试使用坐标时,我不可避免地最终会同时为所有实例更改它们。

我究竟做错了什么?我可以看到我的原始对象仅实例化了 1 个(而不是 4 个 tmes),但我不明白为什么?!?

* * *编辑:根据 hamstergene 的友好建议(见第一个答案),我再次尝试并通过将 *origin 声明为@property 来使其工作。但是,我还必须先@synthesize 它,然后在@implementation 中覆盖它。我不知道为什么,但这对我来说似乎有点矫枉过正。这是正确的方法吗?Xcode 似乎也不喜欢它并发出警报(尽管仍然可以编译)


至于这里的代码是(短):

==================================================== =================================

(坐标对象的包装类接口)

//  XYPoint.h
//

#import <Foundation/Foundation.h>

@interface XYPoint : NSObject

@property float x, y;

-(void) setX: (float) xVal andY: (float) yVal;

@end

==================================================== =================================

(坐标对象的包装类的实现)

//  XYPoint.m
//

#import "XYPoint.h"

@implementation XYPoint

@synthesize x, y;

-(void) setX: (float) xVal andY: (float) yVal {
    x = xVal;
    y = yVal;
}

@end

==================================================== =================================

(我的 Rectangle 类的接口)

//  Rectangle.h
//

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

@interface Rectangle : NSObject

@property   float   width,
                    height;

-(XYPoint *)    origin;
-(void)         setWidth: (float) w andHeight: (float) h;
-(void)         setOrigin: (XYPoint *) pt;
-(void)         printData;

@end

==================================================== =================================

(我的 Rectangle 类的实现)

//  Rectangle.m
//

#import "Rectangle.h"

@implementation Rectangle

@synthesize width, height;

XYPoint *origin;

-(void) setWidth:(float) w andHeight: (float) h {
    width = w;
    height = h;
}

-(XYPoint *) origin {
    return origin;
}

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

    if ( ! origin ) {
        NSLog( @"origin object created" );
        origin = [ [ XYPoint alloc ] init ];
    }
    origin.x = pt.x;
    origin.y = pt.y;
}

-(void) printData {
    NSLog( @"origin coordinates ( %.1f, %.1f )", origin.x, origin.y );
    NSLog( @"Width = %.1f, Height = %.1f\n" );
}

@end

==================================================== =================================

(最后是 main.m)

//  main.m
//

#import "Rectangle.h"

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        XYPoint     *rect1Origin    = [ [ XYPoint alloc ] init ];
        XYPoint     *rect2Origin    = [ [ XYPoint alloc ] init ];
        XYPoint     *rect3Origin    = [ [ XYPoint alloc ] init ];
        XYPoint     *rect4Origin    = [ [ XYPoint alloc ] init ];
        Rectangle   *rect1          = [ [ Rectangle alloc ] init ];
        Rectangle   *rect2          = [ [ Rectangle alloc ] init ];
        Rectangle   *rect3          = [ [ Rectangle alloc ] init ];
        Rectangle   *rect4          = [ [ Rectangle alloc ] init ];

        [ rect1Origin setX: 200 andY: 420 ];
        [ rect1 setOrigin: rect1Origin ];
        [ rect1 setWidth: 250 andHeight: 75 ];
        NSLog( @"1st Rectangle\n------------------------------------------" );
        [ rect1 printData ];

        [ rect2Origin setX: 400 andY: 300 ];
        [ rect2 setOrigin: rect2Origin ];
        [ rect2 setWidth: 100 andHeight: 180 ];
        NSLog( @"2nd Rectangle\n------------------------------------------" );
        [ rect2 printData ];

        [ rect3Origin setX: 99 andY: 99 ];
        [ rect3 setOrigin: rect3Origin ];
        [ rect3 setWidth: 50 andHeight: 450 ];
        NSLog( @"3rd Rectangle\n------------------------------------------" );
        [ rect3 printData ];

        [ rect4Origin setX: 20 andY: 100 ];
        [ rect4 setOrigin: rect4Origin ];
        [ rect4 setWidth: 10 andHeight: 3 ];
        NSLog( @"4th Rectangle\n------------------------------------------" );
        [ rect4 printData ];

        NSLog( @"\n------------------------------------------" );
        NSLog( @"1st Rectangle again...\n------------------------------------------" );
        [ rect1 printData ];

        NSLog( @"2nd Rectangle again...\n------------------------------------------" );
        [ rect2 printData ];

        NSLog( @"3rd Rectangle again...\n------------------------------------------" );
        [ rect3 printData ];

        NSLog( @"4th Rectangle again...\n------------------------------------------" );
        [ rect4 printData ];

        NSLog( @"\n\n********* All rects have the same coordinates why does this happen?" );

    }
    return 0;
}

==================================================== =================================

输出

origin object created
1st Rectangle
------------------------------------------
origin coordinates ( 200.0, 420.0 )
Width = 250.0, Height = 75.0

2nd Rectangle
------------------------------------------
origin coordinates ( 400.0, 300.0 )
Width = 100.0, Height = 180.0

3rd Rectangle
------------------------------------------
origin coordinates ( 99.0, 99.0 )
Width = 50.0, Height = 450.0

4th Rectangle
------------------------------------------
origin coordinates ( 20.0, 100.0 )
Width = 10.0, Height = 3.0

------------------------------------------
1st Rectangle again...
------------------------------------------
origin coordinates ( 20.0, 100.0 )
Width = 250.0, Height = 75.0

2nd Rectangle again...
------------------------------------------
origin coordinates ( 20.0, 100.0 )
Width = 100.0, Height = 180.0

3rd Rectangle again...
------------------------------------------
origin coordinates ( 20.0, 100.0 )
Width = 50.0, Height = 450.0

4th Rectangle again...
------------------------------------------
origin coordinates ( 20.0, 100.0 )
Width = 10.0, Height = 3.0


********* All rects have the same coordinates why does this happen?
4

2 回答 2

3

XYPoint *origin;是一个全局变量,这意味着它在整个程序中共享。您需要将其声明为属性,就像您对x、和所做的y那样。widthheight

于 2013-08-22T07:52:46.350 回答
0

我发现我做错了什么。使用@property/@synthesize 指令可以正常工作,但从技术上讲,问题是一个简单的语法问题,它改变了我的 Rectangle.m 实现中变量 *origin 的范围。

基本上我需要做的就是将变量声明放在大引号之间(没有它们,我无意中将 *origin 设置为全局。)

所以基本上不是这个:

//=======================================    
@implementation Rectangle    
//=======================================    

@synthesize width, height;    

XYPoint *origin;

我应该这样做:

//=======================================  
@implementation Rectangle  
//=======================================  
{  
XYPoint *origin;  
}  

@synthesize width, height;  

Et voila' - 问题解决了。感谢 David Todd(来自:http : //classroomm.com/objective-c/index.php?topic=9389.0)的解决方案(在这里再次感谢 hamstergene 和 rob mayoff)

于 2013-09-01T19:04:16.207 回答