Objective-C中的基本指针/引用问题 - 一个实例中的访问器方法影响类级别的所有实例

时间:2013-08-22 07:48:10

标签: objective-c

我遇到的问题是我怀疑在Objective-C中如何使用指针和引用时的基本错误。我一直在关注这个问题,调整我的代码等等......但无济于事。

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

我欢迎你们自己提出的任何和所有的意见。 :)

如果我可以说明我的问题,那就是这样的:

在我的“main.m”文件中,我实例化了某个“Rectangle”类的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?

2 个答案:

答案 0 :(得分:3)

XYPoint *origin;是一个全局变量,这意味着它在整个程序中共享。您需要将其声明为属性,就像使用xywidthheight一样。

答案 1 :(得分: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)