0

これは、ObjectiveC と Cocoa の学習曲線の一部として、私が書いているプログラムです (他の誰かのプログラムをコピーして学習しないのではなく、自分で作成したものです)。NSView で単純な形状を描画したい (今のところ、楕円形と長方形に限定している)。アイデアは、各 NSBezierPath を NSMutableArray に記録して、保存/読み込み、元に戻す/やり直しも調査/実装できるようにすることです。キャンバスがあり、ツールを選択するために使用する 2 つのボタンと同様に描画できます。パスを処理するために、描画された各オブジェクトの NSBezierPath、色の値、およびサイズの値を保持できる別のオブジェクトを作成しました。これは、配列に格納したいものです。mouseDown/Dragged/Up を使用して、描画パスの座標を取得します。ただし、これは物事が不安定になる場所です。パス/色などを保持するはずのオブジェクトをインスタンス化できます。情報ですが、インスタンス変数を変更しようとすると、アプリがクラッシュし、デバッガーに有用なメッセージが表示されません。コード スニペットは短くするように努めますが、さらに含める必要がある場合は教えてください。コードを機能させるために多くのことを試みたため、コードも少し劣化しました。

プロジェクト: Cocoa ドキュメント ベースのアプリ
次の .m/.h ファイルがあります

  • MyDocument:NSDocument- XCode によって生成された
  • DrawnObject:NSObject- 描画されたオブジェクト、つまりパス、色、タイプ (楕円形/四角形)、およびサイズを処理します
  • Canvas:NSView-まあ、図面を表示し、マウスとボタンを扱います

NSMutableArrayCanvas は、オブジェクトの維持も担当しDrawnObjectます。

DrawnObject.h次のようになります。

#import <Foundation/Foundation.h>
//The drawn object must know what tool it was created with etc as this needs to be used for generating the drawing

@interface DrawnObject : NSObject {
    NSBezierPath * aPath;
    NSNumber * toolType;//0 for oval, 1 for rectangular etc....
    float toolSize;
    struct myCol{
        float rd;
        float grn;
        float blu;
        float alp;
    } toolColor;
}

-(void)setAPath:(NSBezierPath *) path;
-(NSBezierPath *)aPath;
@property (readwrite,assign) NSNumber * toolType;
-(float)toolSize;
-(void)setToolSize:(float) size;
-(struct myCol *)toolColor;
-(void)setCurrentColor:(float)ref:(float)green:(float)blue:(float)alpha;

@end

Canvas.hこのように見えます

#輸入
#import "DrawingObject.h"

@interface Canvas : NSView {
    NSMutableArray * myDrawing;
    NSPoint downPoint;
    NSPoint currentPoint;
    NSBezierPath * viewPath;// ユーザーがマウスをドラッグするとパスを表示します
    NSNumber * currentToolType;
    BOOL mouseUpFlag;//それを機能させるために差分の方法を試しています
    BOOL マウスドラッグ;
}

-(IBAction)useOval:(id)送信者;
-(IBAction)useRect:(id)送信者;
-(IBAction)showTool:(id)送信者;
-(NSRect)currentRect;
-(NSBezierPath *)createPath:(NSRect) aRect;
-(void)setCurrentToolType:(NSNumber *) t;
-(NSNumber *)currentToolType;
@終わり

ファイルには、マウスを処理するためのいくつかの関数があり、Canvas.mNSView/XCode もドロップインされ
-(id)initWithFrame:(NSRect)frame
-(void)drawRect:(NSRect)rectいます。元々mouseUp、新しいものを配列に挿入しようとしてDrawnObjectいましたが、クラッシュが発生しました。そこで、2 つのBOOLフラグを使用して、マウスがいつ離されたかを確認します (不格好ですが、しようとしています....)drawRect配列に挿入します。以下の方法を含め、アプリが失敗する原因を示しました。

- (void)drawRect:(NSRect)rect { //これは自動的に呼び出されます
    // ここにコードを描画します。
    //NSLog(@"drawRect 内のツール タイプは %d です", [self currentTool]);
    NSRect 境界 = [自己境界];
    NSRect aRect = [自己 currentRect];
    viewPath = [self createPath:aRect];
//the createPath method uses the tool type to switch between oval and rect bezier curves

    if(mouseUpFlag==YES && mouseDrag==YES){
        mouseDrag=NO;
        //Create a new drawnObject here 
        DrawnObject * anObject = [[DrawnObject alloc]init];//- WORKS FINE UP TO HERE
        NSLog(@"CREATED NEW drawnObject");
        [anObject setAPath:viewPath]; //- INSTANT APP DEATH!!!!
        NSLog(@"Set a path in drawnObject");
        [anObject setToolType:[[NSNumber alloc]initWithInt:5]];
        NSLog(@"Set toolType in DrawnObject");
        [anObject setToolType:currentToolType];

        [myDrawing addObject:anObject];
        NSLog(@"Added Object");
    }   

    [[NSColor colorWithCalibratedRed:0.0 green:0.9 blue:0.0 alpha:0.5]set];
    [NSBezierPath fillRect:境界];


    [[NSColor lightGrayColor]set];
    [viewPath ストローク]; //これは、ユーザーが描画が行われている場所を確認できるようにするためです

    //ここで、配列にパスを描画します
    [[NSColor blueColor]set];
    for(DrawnObject * myDrawing の indexedObject){
        [[indexedObject aPath] stroke];//これにより、すべてのオブジェクトの実際の描画が行われます

    }


}

これはオブジェクトスコープか何かに関係していると思いますが、私はそれを理解できません。私が言ったように、私がいろいろ試してみると、コードは一種の変容を遂げました。悲しいことに、良い方向ではありません。それらのBOOLSなどのように。

ヘルプ!そこに賢い人がいるなら、私を正しい方向に向けてください!

これを追加:


-(NSBezierPath *)createPath:(NSRect) aRect
{

    NSBezierPath * tempPath;
    //I need to know what tool

    switch(0){  //temporary - this would use the toolType as a selector
        case 0:
            tempPath = [NSBezierPath bezierPathWithOvalInRect:aRect];
            break;
        case 1:
            tempPath = [NSBezierPath bezierPathWithRect:aRect];
            break;
        default:
            tempPath = [NSBezierPath bezierPathWithOvalInRect:aRect];
            break;
    }
    return tempPath;
}
4

6 に答える 6

2

あなたの初期化方法は次のとおりでした:

-(void)init {
[super init];
//set default color = black
toolColor.rd=1.0;
toolColor.grn=1.0;
toolColor.blu=1.0;
toolColor.alp=1.0;
//set default size
toolSize=0.8;
//set default toolType
toolType=0;
//oval
NSLog(@"Init %@",self);
}

これは間違いです。Obj-C ガイドで init メソッドを作成する方法を読むか、サンプル コードを読んでください。これは次のようになります。

-(id)init {
if (self = [super init]) {
    //set default color = black
    toolColor.rd=1.0;
    toolColor.grn=1.0;
    toolColor.blu=1.0;
    toolColor.alp=1.0;
    //set default size
    toolSize=0.8;
    //set default toolType
    toolType=0;
    //oval
    NSLog(@"Init %@",self);
}
return self;
}

-init から何も返さないことで、オブジェクトの作成を妨げていました。幸運を!:-)

編集:アシュリーは私を打ち負かしました...

于 2008-11-28T07:34:50.163 に答える
0

コマンドラインでprint-objectと入力すると、その行にブレークポイントを設定して、そこからステップスルーできます。setAPathがどういうわけか壊れているようです

フリードリヒよろしく

于 2008-11-28T06:05:10.720 に答える
0

ハングするだけです。デバッガーで次のように表示されます。

  [セッションは 2008-11-28 14:40:34 +1000 に開始されました。]
2008-11-28 14:40:36.157 CH18Challenge_try2[1893:10b] (80.000000,285.000000) でマウスダウン
2008-11-28 14:40:36.333 CH18Challenge_try2[1893:10b] マウスアップ (166.000000,217.000000)
2008-11-28 14:40:36.348 CH18Challenge_try2[1893:10b] 初期化
2008-11-28 14:40:36.349 CH18Challenge_try2[1893:10b] 作成された新しい drawObject

[セッションは 2008-11-28 14:40:36 +1000 に開始されました。]
プログラムをデバッガにロード中…
GNU gdb 6.3.50-20050815 (Apple バージョン gdb-962) (2008 年 7 月 26 日土曜日 08:14:40 UTC)
Copyright 2004 Free Software Foundation, Inc.
GDB はフリー ソフトウェアであり、GNU General Public License の対象です。
特定の条件下での変更および/またはコピーの配布を歓迎します。
条件を表示するには、「showcopy」と入力します。
GDB の保証は一切ありません。詳細については、「保証を表示」と入力してください。
この GDB は「i386-apple-darwin」として構成されました。プログラムがロードされました。
共有ライブラリの適用-ロード-ルールすべて
プログラムへの添付: `/Users/johan_kritzinger/Documents/Cocoa/CH18Challenge_try2/build/Debug/CH18Challenge_try2.app/Contents/MacOS/CH18Challenge_try2'、プロセス 1893。
(gdb)

次に、強制終了して停止する必要があります。

于 2008-11-28T04:41:30.263 に答える
0

DrawnObject.m から setAPath の実装を確認する必要があります。また、デバッガーの左上にある「スタック トレース」を見ると、クラッシュがコード内のどこにあるかを示す関数のスタックが一覧表示されます。リリース モードではなく、デバッグ モードで実行していることを確認してください。

于 2008-11-28T04:54:23.843 に答える
0

「クラッシュ」とはどういう意味ですか?

デバッガー コンソール (⇧⌘R) に何か表示されますか?

スタック トレースはデバッガ ウィンドウに表示されますか?

スタック トレースがある場合、コードのどこでクラッシュしますか?

于 2008-11-28T04:26:47.690 に答える
0

あなたが持っているのはクラッシュではありません。クラッシュは、シグナル (EXC_BAD_ACCESS など) が発生したとき、またはキャッチされなかった例外です。

あなたが持っているのは無限ループのようです。

デバッガーの一時停止ボタンを使用して、正確な場所を確認する必要があります。setAPath: メソッドに無限ループがあると思います。この関数が無期限にループしている理由を解明する必要があります。

于 2008-11-29T07:31:33.637 に答える