John
John

Reputation:

Is there somethone wrong with my Object Scope?

This is a program I'm writing (myself as opposed to copying someone else's and thus not learning) as part of the ObjectiveC and Cocoa learning curve. I want to draw simple shapes on a NSView (limiting it to ovals and rectangles for now). The idea is that I record each NSBezierPath to an NSMutableArray so I can also investigate/implement saving/loading, undo/redo. I have a canvas, can draw on it as well as 2 buttons that I use to select the tool. To handle the path I created another object that can hold a NSBezierPath, color values and size value for each object drawn. This is what I want to store in the array. I use mouseDown/Dragged/Up to get coordinates for the drawing path. However, this is where things go wonky. I can instantiate the object that is supposed to hold the path/color/etc. info but, when I try to change an instance variable, the app crashes with no useful message in the debugger. I'll try to keep my code snippets short but tell me if I need to include more. The code has also degenerated a little from me trying so many things to make it work.

Project: Cocoa document based app
I have the following .m/.h files

Canvas is also responsible for maintaining a NSMutableArray of DrawnObject objects.

DrawnObject.h looks like this:

#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 looks like this

#import 
#import "drawnObject.h"

@interface Canvas : NSView {
    NSMutableArray * myDrawing;
    NSPoint downPoint;
    NSPoint currentPoint;
    NSBezierPath * viewPath;//to show the path as the user drags the mouse
    NSNumber * currentToolType;
    BOOL mouseUpFlag;//trying a diff way to make it work
    BOOL mouseDrag;
}

-(IBAction)useOval:(id)sender;
-(IBAction)useRect:(id)sender;
-(IBAction)showTool:(id)sender;
-(NSRect)currentRect;
-(NSBezierPath *)createPath:(NSRect) aRect;
-(void)setCurrentToolType:(NSNumber *) t;
-(NSNumber *)currentToolType;
@end

In the Canvas.m file there are several functions to deal with the mouse and NSView/XCode also dropped in
-(id)initWithFrame:(NSRect)frame
and -(void)drawRect:(NSRect)rect Originally I use mouseUp to try to insert the new DrawnObject into the array but that caused a crash. So, now I use two BOOL flags to see when the mouse was released (clunky but I'm trying....)in drawRect to insert into the array. I've included the method below and indicated where it causes the app to fail:

- (void)drawRect:(NSRect)rect { //This is called automatically
    // Drawing code here.
    //NSLog(@"Within drawRect tool type is %d", [self currentTool]);
    NSRect bounds = [self bounds];
    NSRect aRect = [self 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:bounds];


    [[NSColor lightGrayColor]set];
    [viewPath stroke]; //This is so the user can see where the drawing is being done

    //Now, draw the paths in the array
    [[NSColor blueColor]set];
    for(DrawnObject * indexedObject in myDrawing){
        [[indexedObject aPath] stroke];//This will do the actual drawing of ALL objects

    }


}

I guess this has something to do with object scope or something but I just can not figure it out. As I said, as I've tried things the code has sort of undergone an metamorphosis, sadly not for the better. Like those BOOLS etc.

HELP! Any clever people out there, point me in the right direction please!

ADDED THIS ON:


-(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;
}

Upvotes: 0

Views: 3807

Answers (6)

Matt Gallagher
Matt Gallagher

Reputation: 14968

What you have is not a crash. A crash is when a signal is raised (like EXC_BAD_ACCESS) or an uncaught exception.

What you have seems to be an infinite loop.

You need to use the pause button in the Debugger and see exactly where. I would guess that you have an infinite loop in your setAPath: method. You need to work out why this function is looping indefinitely.

Upvotes: 0

Adam Ernst
Adam Ernst

Reputation: 54060

You said your init method was:

-(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);
}

This is definitely wrong; read up on how to create an init method in the Obj-C guide or by reading sample code. Here's what it should look like:

-(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;
}

By not returning anything from -init, you were preventing the object's creation. Good luck! :-)

Edit: Ashley beat me to it...

Upvotes: 2

Friedrich
Friedrich

Reputation: 5996

On the command line you can type print-object and you can set a breakpoint in that line and step through it from there. It seems setAPath is somehow broken

Regards Friedrich

Upvotes: 0

Adam Ernst
Adam Ernst

Reputation: 54060

We need to see the implementation of setAPath from DrawnObject.m. Also, for the "stack trace" look on the upper left of the debugger--it should list a stack of functions showing where in your code the crash is. Make sure you're running in Debug mode, not Release.

Upvotes: 0

John
John

Reputation:

It just hangs. In the debugger I see:

  [Session started at 2008-11-28 14:40:34 +1000.]
2008-11-28 14:40:36.157 CH18Challenge_try2[1893:10b] Mouse Down at (80.000000,285.000000)
2008-11-28 14:40:36.333 CH18Challenge_try2[1893:10b] Mouse Up at (166.000000,217.000000)
2008-11-28 14:40:36.348 CH18Challenge_try2[1893:10b] Init 
2008-11-28 14:40:36.349 CH18Challenge_try2[1893:10b] CREATED NEW drawnObject

[Session started at 2008-11-28 14:40:36 +1000.]
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/johan_kritzinger/Documents/Cocoa/CH18Challenge_try2/build/Debug/CH18Challenge_try2.app/Contents/MacOS/CH18Challenge_try2', process 1893.
(gdb) 

Then I have to force quit to stop it.

Upvotes: 0

Peter Hosey
Peter Hosey

Reputation: 96333

What do you mean by “crash”?

Does anything appear in the Debugger Console (⇧⌘R)?

Does a stack trace appear in the Debugger window?

If there's a stack trace, where in your code does it crash?

Upvotes: 0

Related Questions