NSArrayController addObject Возвращает ноль - PullRequest
0 голосов
/ 06 января 2010

У меня есть приложение для обработки основных данных с двумя NIB, главное окно с парой NSTableView и форма для добавления контента. Форма имеет NSTextView и NSTextField. У меня есть две сущности в основных данных, и я управляю контентом с помощью двух NSArrayControllers. С одним NSArrayController следующий код в моем AppDelegate отлично работает для добавления контента:

    id o = [bookController newObject];
    [o setValue:@"Drafts" forKey:@"bookName"];
    [o setValue:0 forKey:@"sortOrder"];
    [bookController addObject:o];

Но этот код в моем классе AppController всегда возвращает нуль:

NSObject *o = [chapterArrayController newObject];

[o setValue:contentOfchapter forKey:@"chapterText"];
[o setValue:chapterTitleString forKey:@"chapterTitle"];
[o setValue:@"Drafts" forKey:@"bookChapter"];
NSLog(@"Where is the object?: %@", o);
[chapterArrayController addObject:o];

Кажется, что chapterArrayController не связан с сущностью Chapter в основных данных, но привязки в IB верны. Я думаю, что это как-то связано с несколькими перьями, но я немного растерялся.

Любые указатели в правильном направлении приветствуются.

Спасибо.

Обновление 2: я создал класс с именем JBAddChapter, который выглядит следующим образом:

JBAddChapter.h

#import <Cocoa/Cocoa.h>


@interface JBAddChapter : NSObject {

IBOutlet NSArrayController *bookController;
IBOutlet NSArrayController *chapterArrayController;

}
- (IBAction)testArrayControllers:(id)sender;
+ (void)getChapterData:(NSString *)passedChapterTitle withChapterText:(NSString *)passedChapterText;
- (void)standAloneTestArrayControllers;

@end

JBAddChapter.m

#import "JBAddChapter.h"


@implementation JBAddChapter


+ (void)getChapterData:(NSString *)passedChapterTitle withChapterText:(NSString *)passedChapterText;
{
    [[self alloc] standAloneTestArrayControllers];
}


- (IBAction)testArrayControllers:(id)sender
{
    [self standAloneTestArrayControllers];
}

- (void)standAloneTestArrayControllers
{
    [chapterArrayController fetchWithRequest:nil merge:NO error:nil];
    NSLog(@"1. chapterArrayController %@", chapterArrayController);

    NSArray *a = [chapterArrayController arrangedObjects];
    NSLog(@"2. NSArray a = %@", a);

    NSUInteger numberOfMenuItems = [a count];
    NSLog(@"3. Count of items in array: %d", numberOfMenuItems);

    [bookController fetchWithRequest:nil merge:NO error:nil];
    NSLog(@"1. bookController %@", chapterArrayController);

    NSArray *b = [chapterArrayController arrangedObjects];
    NSLog(@"2. NSArray b = %@", b);

    NSUInteger newNumberOfMenuItems = [a count];
    NSLog(@"3. Count of items in array: %d", newNumberOfMenuItems);
}
@end

Я создал две кнопки в IB в моем главном окне и подключил одну к IBAction testArrayControllers выше. Другая кнопка, которую я подключаю к AppController и этому IBAction:

- (IBAction)testArrayControllers:(id)sender
{
    [JBAddChapter getChapterData:nil withChapterText:nil];
}

Если я вызываю standAloneTestArrayControllers из IBAction JBAddChapter, все работает нормально. Если я вызываю тот же метод из AppController, используя фабричный метод в JBAddChapter, то у контроллеров массива ноль.

2010-01-07 06:15:36.971 Scout[3881:a0f] 1. chapterArrayController <NSArrayController: 0x200060b40>[entity: Chapter, number of selected objects: 1]
2010-01-07 06:15:36.972 Scout[3881:a0f] 2. NSArray a = (
loads of stuff
)
2010-01-07 06:15:36.973 Scout[3881:a0f] 3. Count of items in array: 9
2010-01-07 06:15:36.974 Scout[3881:a0f] 1. bookController <NSArrayController: 0x200060b40>[entity: Chapter, number of selected objects: 1]
2010-01-07 06:15:36.978 Scout[3881:a0f] 2. NSArray b = (
loads of stuff
)
2010-01-07 06:15:36.979 Scout[3881:a0f] 3. Count of items in array: 8
2010-01-07 06:15:38.402 Scout[3881:a0f] 1. chapterArrayController (null)
2010-01-07 06:15:38.402 Scout[3881:a0f] 2. NSArray a = (null)
2010-01-07 06:15:38.402 Scout[3881:a0f] 3. Count of items in array: 0
2010-01-07 06:15:38.403 Scout[3881:a0f] 1. bookController (null)
2010-01-07 06:15:38.403 Scout[3881:a0f] 2. NSArray b = (null)
2010-01-07 06:15:38.403 Scout[3881:a0f] 3. Count of items in array: 0

Итак, почему контроллеры массива возвращают ноль из одного метода, а не из другого? Насколько я могу судить, все привязки в IB верны.

Ответы [ 3 ]

0 голосов
/ 07 января 2010
[[self alloc] standAloneTestArrayControllers];

Никогда не делай этого. Всегда инициализируйте экземпляр, отправив ему сообщение init (или initWithSomethingElse:, в зависимости от инициализаторов, предоставляемых классом). Если вы отправите любое другое сообщение недавно выделенному, но еще не инициализированному экземпляру, результаты будут неопределенными и почти наверняка неверными.

[bookController fetchWithRequest:nil merge:NO error:nil];
NSLog(@"1. bookController %@", chapterArrayController);

Вы уверены, что не хотите регистрировать bookController здесь, а не chapterArrayController?

Если я вызываю standAloneTestArrayControllers из IBAction JBAddChapter, все работает нормально. Если я вызываю тот же метод из AppController, используя фабричный метод в JBAddChapter, то у контроллеров массива ноль.

Потому что вы еще не загрузили перо. Ни вы не загрузили объект главы из пера, ни объект главы не загрузили сам перо, ни что-либо явно (как в setChapterArrayController:), не предоставив объекту главы контроллер массива для хранения.

Он работает из метода действия, потому что в этом контексте вы загрузили перо.

Итак, почему контроллеры массива возвращают ноль из одного метода, а не из другого?

Контроллеры массива не возвращаются nil; они не существуют. (Более того, функции и методы возвращают значения, а не объекты или классы.) Переменные, которые вы создали для хранения контроллеров массива, содержат nil, потому что вы не поместили туда никаких контроллеров массива.

Предполагая, что JBAddChapter предназначен для владения листом главы добавления, он должен загрузить перо (или создать экземпляр контроллера окна) в его методе init, и вы должны либо создать объект от владельца основного окна (и этот объект владеет объектом add-chapter и только когда-либо использует принадлежащий ему объект add-chapter) или делает объект add-chapter одноэлементным. С первым легче.

И, конечно, когда вы создаете этот объект или любой другой, вы должны всегда использовать пару alloc + init / initWith… (или предоставленный удобный метод автоматического освобождения); в противном случае, как и сейчас, ваш объект не будет загружать свое перо, потому что вы никогда не отправляли ему сообщение init.

0 голосов
/ 08 января 2010

Думаю, я отвечу на свой вопрос здесь. Что-то не так в моей NIB, и как только я удалил свои контроллеры массива и снова подключил их в IB, все просто снова автоматически сработало.

0 голосов
/ 06 января 2010

Имеет ли chapterArrayController значение nil, когда вы запрашиваете объект?

Вы говорите, что у вас есть два пера ... в этом втором пуле экземпляр chapterArrayController создан? Если да, был ли загружен перо к моменту вызова newObject?

...