Что-то не так с моим объектом?

Это программа, которую я пишу (я сам в отличие от копирования чужого и, следовательно, не учусь) как часть кривой обучения ObjectiveC и Cocoa. Я хочу нарисовать простые формы на NSView (ограничивая его овалами и прямоугольниками на данный момент). Идея состоит в том, что я записываю каждый NSBezierPath в NSMutableArray, чтобы я мог также исследовать / реализовать сохранение / загрузку, отменить / повторить. У меня есть холст, я могу нарисовать на нем, а также 2 кнопки, которые я использую для выбора инструмента. Чтобы обработать путь, я создал другой объект, который может содержать NSBezierPath, значения цвета и значения размера для каждого нарисованного объекта. Это то, что я хочу хранить в массиве. Я использую mouseDown / Dragged / Up, чтобы получить координаты пути рисования. Тем не менее, это то, где дела идут плохо. Я могу создать экземпляр объекта, который должен содержать путь / цвет / и т. Д. информация, но, когда я пытаюсь изменить переменную экземпляра, приложение вылетает без полезного сообщения в отладчике. Я постараюсь сделать свои фрагменты кода короткими, но скажите, нужно ли мне добавить больше. Код также немного выродился из-за того, что я пытался сделать так много вещей, чтобы он работал.

Проект: приложение на основе документов Какао У
меня есть следующие файлы .m / .h

  • MyDocument:NSDocument - генерируется XCode
  • DrawnObject:NSObject - имеет дело с нарисованным объектом, т.е. путем, цветом, типом (овал / прямоугольник) и размером
  • Canvas:NSView - хорошо, показывает рисунок, разбирается с мышью и кнопками

Холст также несет ответственность за поддержание NSMutableArrayиз 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 "drawnObject.h"

@interface Canvas: NSView {
    NSMutableArray * myDrawing;
    NSPoint downPoint;
    NSPoint currentPoint;
    NSBezierPath * viewPath; // чтобы показать путь, когда пользователь перетаскивает мышь
    NSNumber * currentToolType;
    BOOL mouseUpFlag; // пробуем другой способ заставить его работать
    BOOL mouseDrag;
}

- (IBAction) useOval: (ID) отправителя;
- (IBAction) useRect: (ID) отправителя;
- (IBAction) showTool: (ID) отправителя;
- (NSRect) currentRect;
- (NSBezierPath *) createPath: (NSRect) aRect;
- (void) setCurrentToolType: (NSNumber *) t;
- (NSNumber *) currentToolType;
@конец

В Canvas.mфайле есть несколько функций для работы с мышью, и NSView / XCode также вставлен,
-(id)initWithFrame:(NSRect)frame
и -(void)drawRect:(NSRect)rectПервоначально я использую, mouseUpчтобы попытаться вставить новое DrawnObjectв массив, но это вызвало сбой. Итак, теперь я использую два BOOLфлага, чтобы увидеть, когда мышь была выпущена (неуклюже, но я пытаюсь ....), drawRectчтобы вставить в массив. Я включил метод ниже и указал, где он вызывает сбой приложения:

- (void) drawRect: (NSRect) rect {// Вызывается автоматически
    // Рисуем код здесь.
    // NSLog (@ "Тип инструмента drawRect -% d", [self currentTool]);
    NSRect bounds = [собственные границы];
    NSRect aRect = [self currentRect];
    viewPath = [self createPath: aRect];
// метод createPath использует тип инструмента для переключения между овальными и прямоугольными кривыми Безье

    if (mouseUpFlag == YES && mouseDrag == YES) {
        MouseDrag = NO;
        // Создаем новый DrawObject здесь 
        DrawnObject * anObject = [[DrawnObject alloc] init]; // - РАБОТАЕТ ОТЛИЧНО ЗДЕСЬ
        NSLog (@ "CREATED NEW drawnObject");
        [anObject setAPath: viewPath]; // - мгновенная смерть приложения !!!!
        NSLog (@ "Установить путь в drawObject");
        [anObject setToolType: [[NSNumber alloc] initWithInt: 5]];
        NSLog (@ "Установить toolType в DrawnObject");
        [anObject setToolType: currentToolType];

        [myDrawing addObject: anObject];
        NSLog (@ "Добавленный объект");
    }   

    [[NSColor colorWithCalibratedRed: 0,0 зеленого цвета: 0,9 синего цвета: 0,0 альфа: 0,5] установлено];
    [NSBezierPath fillRect: границы];


    [[NSColor lightGrayColor] set];
    [viewPath stroke]; // Это так, чтобы пользователь мог видеть, где делается рисунок

    // Теперь нарисуем пути в массиве
    [[NSColor blueColor] set];
    for (DrawnObject * indexedObject в myDrawing) {
        [[indexedObject aPath] stroke]; // Это будет фактически рисовать ВСЕ объекты

    }


}

Я предполагаю, что это как-то связано с областью объекта или чем-то еще, но я просто не могу понять это. Как я уже сказал, когда я пробовал что-то, код претерпел метаморфозу, к сожалению, не в лучшую сторону. Как эти БУЛЫ и т. Д.

ПОМОГИТЕ! Любые умные люди, направьте меня в правильном направлении, пожалуйста!

ДОБАВИЛ НА ЭТОМ:


-(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;
}
28.11.2008 04:04:02
Нам нужно увидеть реализацию setAPath из DrawnObject.m.
Adam Ernst 28.11.2008 04:26:57
- (void) setAPath: (NSBezierPath *) path {NSLog (@ "Recorded Path"); aPath = путь; }
Eggs McLaren 28.11.2008 04:53:30
Я предполагаю, что должен сделать бит release / retain, но дело в том, что в методе он даже не доходит до NSLog.
Eggs McLaren 28.11.2008 04:55:05
Какой у вас метод -init в DrawnObject.m? Возможно, инициализация неверна, поэтому при попытке доступа к иварам происходит сбой. Пройдите через отладчик. Обязательно ознакомьтесь с рекомендациями по управлению памятью - в вашем коде есть некоторые нарушения, но ничего такого, что могло бы вызвать сбой.
Adam Ernst 28.11.2008 05:01:50
<code> - (void) init {[super init]; // установить цвет по умолчанию = черный toolColor.rd = 1.0; toolColor.grn = 1,0; toolColor.blu = 1,0; toolColor.alp = 1,0; // установить размер по умолчанию toolSize = 0.8; // установить значение по умолчанию toolType toolType = 0; // овальный NSLog (@ "Init% @", self); } </ code> Ребята, вы молодцы.
Eggs McLaren 28.11.2008 05:08:50
6 ОТВЕТОВ

Что вы подразумеваете под «сбой»?

Что-нибудь появляется в консоли отладчика (⇧⌘R)?

Трассировка стека появляется в окне отладчика?

Если есть трассировка стека, где в вашем коде происходит сбой?

0
28.11.2008 04:26:47

Это просто висит. В отладчике я вижу:

  [Сессия началась в 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] СОЗДАН НОВЫЙ drawObject

[Сессия началась в 2008-11-28 14:40:36 +1000.]
Загрузка программы в отладчик…
GNU gdb 6.3.50-20050815 (версия Apple gdb-962) (сб 26 июля 08:14:40 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB - это бесплатное программное обеспечение, на которое распространяется Стандартная общественная лицензия GNU, и вы
добро пожаловать изменить его и / или распространять его копии при определенных условиях.
Введите «показать копирование», чтобы увидеть условия.
На GDB нет абсолютно никаких гарантий. Тип "показать гарантию" для деталей.
Эта GDB была настроена как "i386-apple-darwin". Программа загружена.
sharedlibrary apply-load-rules все
Присоединение к программе: `/Users/johan_kritzinger/Documents/Cocoa/CH18Challenge_try2/build/Debug/CH18Challenge_try2.app/Contents/MacOS/CH18Challenge_try2 ', процесс 1893.
(GDB) 

Тогда я должен заставить бросить курить, чтобы остановить это.

0
28.11.2008 04:41:30
Извините, это была консоль отладки. В Отладчике, который я вижу, это указывает, что <em> indexedObject находится вне области </ em>. И это то, что я не понимаю. Я, вероятно, просто медленнее в освоении .. Как я уже говорил, я нуб - где мне искать трассировку стека?
Eggs McLaren 28.11.2008 04:48:08
Если произошел сбой до того, как он попал в цикл for, тогда переменная indexedObject еще не существует. Как выглядит реализация createPath:
Ashley Clark 28.11.2008 05:32:01
case 0: tempPath = [NSBezierPath bezierPathWithOval: aRect]; перемена; // другие случаи, например для rectabngle} // close switch retuen tempPath; }
Eggs McLaren 28.11.2008 05:48:16
Трассировка стека находится в верхнем левом списке в окне отладчика. Ваша проблема в том, что bezierPathWithOval: не существует. Правильный селектор bezierPathWithOvalInRect :.
Peter Hosey 30.11.2008 07:27:28

Нам нужно увидеть реализацию setAPath из DrawnObject.m. Кроме того, для «трассировки стека» посмотрите в верхнем левом углу отладчика - он должен перечислить стек функций, показывающих, где в вашем коде происходит сбой. Убедитесь, что вы работаете в режиме отладки, а не в версии.

0
28.11.2008 04:54:23
Если я правильно понимаю, это то, что говорит трассировка стека (есть 22 элемента, но только один черный): - [Canvas drawRect:], и если я нажму на это, правая панель отладчиков говорит, что indexedObject выходит из области видимости. Может быть, моя реализация цикла for неверна в drawRect?
Eggs McLaren 28.11.2008 05:04:04
Нет, сбой не имеет ничего общего с indexedObject или циклом. «out of scope» просто означает, что вы еще не попали в цикл for, поэтому объект находится «вне области».
Adam Ernst 28.11.2008 07:29:21

В командной строке вы можете напечатать print-object и установить точку останова в этой строке и пройти через нее оттуда. Кажется, setAPath как-то сломан

С уважением Фридрих

0
28.11.2008 06:05:10

Вы сказали, что ваш метод инициализации был:

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

Это определенно неправильно; читайте о том, как создать метод init, в руководстве Obj-C или читая пример кода. Вот как это должно выглядеть:

-(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, вы препятствовали созданию объекта. Удачи! :-)

Редактировать: Эшли избил меня до этого ...

2
28.11.2008 07:34:50

То, что у вас есть, не является крахом. Сбой - это когда возникает сигнал (например, EXC_BAD_ACCESS) или необработанное исключение.

То, что у вас есть, кажется бесконечной петлей.

Вам нужно использовать кнопку паузы в отладчике и посмотреть, где именно. Я предполагаю, что у вас есть бесконечный цикл в вашем setAPath: метод. Вам нужно выяснить, почему эта функция работает бесконечно.

0
29.11.2008 07:31:33