Цель C: вопрос о синтаксисе - как инициализировать массив, который «живет» глубоко в иерархии объектов - PullRequest
1 голос
/ 14 февраля 2011

All - спасибо за прекрасную инструкцию, которую вы предоставили.Я думаю, что этот набросок внесет ясность в то, чего я пытаюсь достичь.

По сути, я хочу создать приложение для iPhone, которое позволит пользователю выбирать школьный округ из таблицы, и приложение будет перемещать этот вид и отображатьследующий стол, полный школ.Когда они выбирают школу, в следующем представлении отображаются учителя, и, наконец, когда они выбирают учителя, в нем отображаются курсы, преподаваемые этим учителем.

Итак, я пытаюсь составить некоторые примеры данных для моей просматриваемой таблицы."развертка", и я изо всех сил пытаюсь заполнить такую ​​иерархическую структуру данных.

Я надеюсь, что скриншот ниже поможет.

https://skitch.com/aibkwik/rqu41/photo-feb-13-10-30-15-pm.jpg

Исходная запись следует:

ОБНОВЛЕНО: я пытаюсь выделить массив, глубоко внедренный в иерархию объектов.Верхний экземпляр объекта называется «thisYear», и в нем есть массив с именем «courses».«курсы» также содержит, помимо прочего, массив с именем ScoreCatetories.Как бы вы инициализировали и добавили объект в массив "ScoreCategories"?Я пробовал множество вещей, в том числе:

Я пробую всевозможные комбинации, например, приведенную ниже - ничего не работает.

...
[[thisYear courses] scoreCategories] = [[NSMutableArray alloc] init];
[[[thisYear courses] scoreCategories] addObject:myNewObj]; 
...
I'm trying to load some sample data -  the code below is located in the

didFinishLaunchingWithOptions функция appDelegate.

Вот фрагмент кода, который вызывает у меня горе.Пожалуйста, смотрите .h файлы, далее в этом посте.

dGradeURin *thisYear;
thisYear = [[dGradeURin alloc] init];
[thisYear.howManyTerms initWithInteger: 4];
thisYear.gradeURin = @"Freshman";
//this paragraph compiles and runs fine
dCourse *tmpcourse;
tmpcourse = [[dCourse alloc] init];
tmpcourse.cName =@"Computer Science";
tmpcourse.school =@"Freedom High";
thisYear.courses = [[NSMutableArray alloc] init];
[thisYear.courses addObject:tmpcourse];


dScoringCategory *tmpSC;
tmpSC =  [[dScoringCategory alloc] init];
tmpSC.name = @"Quizzes";

//these two lines are not working
[[thisYear courses] setScoreCategories:[[[NSMutableArray alloc] init] autorelease]];
[[[thisYear courses] scoreCategories] addObject:tmpSC];     

//both the above lines compile with a warning:  NSMutableArray may not responde to -setScoreCategories
// when I run the program, the first line causes crash with an exception... See stack trace at far bottom

Любая помощь с благодарностью.

==================

Вот фрагменты файла заголовка .h для каждого определения объекта интерфейса, по сути ...

@ interface dGradeURin: NSObject {

NSNumber *howManyTerms;
NSString  *gradeURin;

NSMutableArray *courses;

}

@ property (retain, nonatomic) NSNumber * howManyTerms;@property (retain, nonatomic) NSString * gradeURin;@property (retain, nonatomic) NSMutableArray * courses;

@interface dCourse  : NSObject {
    NSString *cName;
    NSString *teacher;
    NSString *school;
    NSString *school_term;
    NSString *gradingMethod;
    NSNumber *whichterm;

    NSMutableArray  *scoreCategories;
}

@property (retain, nonatomic) NSString *cName;
@property (retain, nonatomic) NSString *school;
@property (retain, nonatomic) NSMutableArray *scoreCategories;





@interface dScoringCategory : NSObject {
NSString *name;
NSMutableArray *scores;

}

@ property (retain, nonatomic) NSString * name;@property (сохранение, неатомное) NSMutableArray * оценки;

@ интерфейс dScore: NSObject {

NSNumber    *score;
NSDate      *scoreDate;
NSString    *description;

}

@ свойство (сохранить, неатомное) NSDate * scoreDate;@property (сохранить, неатомный) NSNumber * оценка;@property (retain, nonatomic) NSString * description;

=============================== Здесьэто трассировка стека

2011-02-13 21: 49: 43.559 GradeJanx [86526: 40b] - [ NSArrayM setScoreCategories:]: нераспознанный селектор, отправленный экземпляру 0x4b76660 2011-02-13 21:49: 43.561 GradeJanx [86526: 40b] * Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: '- [__ NSArrayM setScoreCategories:]: нераспознанный селектор, отправленный экземпляру 0x4b76660' * Вызовстек при первом выбросе: (0 CoreFoundation 0x00db0be9 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x00f055c2 objc_exception_throw + 47 2 CoreFoundation 0x00db26fb - [NSObject (NSObject) не делает переадресацию 056 * 056 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 030 * 0: 0 * * 0 * * 0 * * 0 * 030 * 030 * 0: 030 * 030 * 0: 030 * 0: 030 * 030: 030: 030: 030: 0: 0: 0 * 0: 0 * 0: 0 * * 0: 0 * * 0: 0 * * 0: 0 * 0 * 0 * 0 030 * 030 * 0: 0 * 0: 0 * 0: 0 *.+ 966 4 CoreFoundation 0x00d21f22 _CF_forwarding_prep_0 + 50 5 GradeJanx 0x00002c50 - [приложение AppDelegate_iPhone: didFinishLaunchingWithOptions:] + 881 6 UIKit 0x002ba1fa - [UIApplication _callInitializationgatesForURL: полезная нагрузка: приостановлено:] + 1163 7 UIKit 0x002bc55e - [UIApplication _runWithURL: полезная нагрузка: launchOrientation: statusBarStyle: statusBarHidden:] + 439 8 UIKit 0x002c6db2 - [дескриптор UIApplicationEvent: отправка UIA для использования при добавлении события: 0EE: 0EB2EIK: отправка приложения UIA: 0EEE: 0EE: 0+ 71 10 UIKit 0x002c4732 _UIApplicationHandleEvent + 7576 11 GraphicsServices 0x016e6a36 PurpleEventCallback + 155012 CoreFoundation 0x00d92064 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52 13 CoreFoundation 0x00cf26f7 __CFRunLoopDoSource1 + 215 14 CoreFoundation 0x00cef983 __CFRunLoopRun + 979 15 CoreFoundation 0x00cef240 CFRunLoopRunSpecific + 208 16 CoreFoundation 0x00cef161 CFRunLoopRunInMode + 97 17 UIKit 0x002bbfa8 - [UIApplication _run] + 636 18 UIKit 0x002c842e UIApplicationMain + 1160 19 GradeJanx 0x000028bc основной + 102 20 GradeJanx 0x0000284d start + 53

Ответы [ 5 ]

3 голосов
/ 14 февраля 2011

Хорошо, это все запутано, так что давайте немного отступим назад. Массив - это индексированный набор объектов. Индекс представляет собой неотрицательное целое число, которое представляет местоположение объекта. Каждый объект доступен в массиве по индексу. Вы не можете сделать [[thisYear courses] scoreCategories] и ожидать, что что-нибудь сработает, потому что вы фактически не указали индекс для объекта в массиве. Вы можете сделать что-то вроде [[thisYear courses] objectAtIndex:0], которое вернет первый элемент в массиве. Вы также можете сделать [[thisYear courses] objectAtIndex:1], что вернет второй элемент в массиве.

Каждый раз, когда вы вставляете элемент в NSMutableArray, он вставляется как последний объект в массиве. Например, если NSMutableArray, в который вы вставляете свой объект, не содержит никаких элементов, содержащихся в нем, индекс вставляемого вами элемента равен 0. Если в нем есть 1 элемент, то индекс вставляемый элемент будет иметь индекс 1.

Код, который вы, вероятно, ищете, это:

NSMutableArray *scoreCategories = [NSMutableArray array];
[scoreCategories addObject:myNewObj];
[[thisYear courses] addObject:scoreCategories];

Тем не менее, существует множество других проблем, связанных с этим. Прежде чем продолжить, я бы порекомендовал вам провести некоторое время с хорошей книгой Objective-C .

Обновление

Хорошо, давайте еще раз посмотрим на это. Это довольно сложно без контекста, в котором этот код появляется, но мы все равно попробуем.

dGradeURin *thisYear = [[[dGradeURin alloc] init] autorelease];

thisYear.howManyTerms = [NSNumber numberWithInteger:4];
thisYear.gradeURin = @"Freshman";

NSMutableArray *courses = [NSMutableArray array];

//set up a temporary course
dCourse *temporaryCourse = [[[dCourse alloc] init] autorelease];
temporaryCourse.cName = @"Computer Science";
temporaryCourse.school = @"Freedom High";
temporaryCourse.scoreCategories = [NSMutableArray array];

dScoringCategory *temporaryScoringCategory = [[[dScoringCategory alloc] init] autorelease];
temporaryScoringCategory.name = @"Quizzes";

[temporaryCourse.scoreCategories addObject:temporaryScoringCategory];

[courses addObject: temporaryCourse];
thisYear.courses = courses;

Эта первая строка создает объект с автоматическим освобождением. Это означает, что в какой-то момент память, занятая этим объектом, будет освобождена для использования в другом месте. Если вы не освободите память объекта, он будет продолжать занимать память независимо от того, используете вы ее или нет. Подробнее об этом (и вам действительно необходимо понять, чтобы использовать Objective-C), ознакомьтесь с документацией Apple .

Пара других вещей. Если это домашнее задание и похоже, что оно из содержания, то убедитесь, что вы отметили его как домашнее задание . Я не против помочь вам здесь, потому что похоже, что большинство ваших проблем синтаксические, но не забывайте в следующий раз.

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

0 голосов
/ 14 февраля 2011

Я ненавижу быть тем парнем, но такой глубокий осмотр (заимствованный термин, ха!) Пахнет для меня как плохой дизайн.
Вот что я бы сделал:
Имейте свойство courses объекта thisYear, которое заполняется при необходимости. courses - это массив, содержащий Course объектов. У объекта Course есть свойство с именем scoreCategories, а также метод addScoreCategory. Так что для вашего кода выше, вы бы сделали

 Course * currentCourse = [[thisYear courses] objectAtIndex:0]; // assuming you want the first course
  if ([currentCourse isKindOfClass:[Course class]]) {
    [currentCourse addScoreCategory:myNewObj];
  }

В addScoreCategory или в методе init класса Course вы должны создать NSMutableArray и присвоить его свойству scoreCategories.

0 голосов
/ 14 февраля 2011

Если это объявленное свойство (с синтаксисом @property), то вы можете использовать точечную запись для установки значения свойства:

// This assumes that scoreCategories has either the 'retain' or 'copy' property;
// if it instead uses 'assign', then you'll need to retain this array.
[thisYear courses].scoreCategories = [NSMutableArray arrayWithObjects:myNewObj, nil];

Если это не объявленное свойство, просто получите к нему доступ, используя стандартное обозначение стрелки:

[thisYear courses]->scoreCategories = [[NSMutableArray alloc] initWithObjects:myNewObj, nil];
0 голосов
/ 14 февраля 2011

Не самый чистый подход, но все равно:

[[thisYear courses] setScoreCategories:[[[NSMutableArray alloc] init] autorelease]];
[[[thisYear courses] scoreCategories] addObject:myNewObj]; 
0 голосов
/ 14 февраля 2011

Что-то вроде

for (Course *course in thisYear.courses) {
  course.scoreCategories = [[[NSMutableArray alloc] init] autorelease];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...