1

Objective-C でポインタと参照がどのように使用されているかを理解する上での基本的なエラーであると思われるものに問題があります。私は問題を見続けたり、コードを微調整したりしていますが、役に立ちません。

私はどこかで単純なエラーを起こしていることを知っています(Objective-Cの初心者ですが、OOPの初心者ではありません)が、それがわかりません... argh :P

あなたのような賢明な方からのあらゆる意見を歓迎します。:)

私の問題を説明するとしたら、次のようになります。

私の「main.m」ファイルでは、特定の「Rectangle」クラスの 4 つの個別のインスタンスをインスタンス化し、それぞれがゲッター/セッターを介してアクセスできる一意の寸法とデカルト座標を持っています。「幅」と「高さ」のプロパティは合成され、座標はカスタム メソッドを介してアクセス可能なオブジェクト (XYPpoint クラス) 内にラップされます。

幅と高さのプロパティにアクセスすると、すべてのインスタンスの一意の値を取得/設定できますが、座標でそれを試みると、必然的にすべてのインスタンスの値を同時に変更することになります。

私は何を間違っていますか?元のオブジェクトが (4 回ではなく) 1 回だけインスタンス化されていることがわかりますが、その理由がわかりません?!?

* * *編集: hamstergene の親切な提案 (1 番目の回答を参照) に従って、もう一度試してみたところ、*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

0

私は自分が何を間違っていたかを知りました。@property/@synthesize ディレクティブを使用すると問題なく動作しますが、技術的には、Rectangle.m 実装の変数 *origin のスコープを変更する単純な構文の問題でした。

基本的には、変数宣言を中引用符で囲むだけで済みました (中引用符がないと、うっかり *origin をグローバルに設定してしまいます)。

したがって、基本的にこれの代わりに:

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

@synthesize width, height;    

XYPoint *origin;

私はこれをすべきだった:

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

@synthesize width, height;  

出来上がり - 問題は解決しました。David Todd (from : http://classroomm.com/objective-c/index.php?topic=9389.0 ) のソリューションに感謝します (ここでも hamstergene と rob mayoff に感謝します)。

于 2013-09-01T19:04:16.207 に答える