2010-01-06 7 views
0

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

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 правильны. Я думаю, что это имеет какое-то отношение к множеству ножей, но я здесь как-то в порядке.

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

Спасибо.

Update 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 в моем главном окне, и подключил один к testArayControllers IBAction выше. Другая кнопка я подключить к 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 правильны.

+0

Вы должны использовать 'NSUInteger' для возвращаемого значения' count'. 'int' слишком короток на 64-битных машинах, а неправильная подпись (значения могут быть отрицательными, что не имеет смысла для подсчета вещей). –

+0

Спасибо, Питер, я сделал вашу предложенную настройку. –

ответ

0

Это главаArrayController nil, когда вы запрашиваете его для объекта?

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

+0

Ну, я заставляю chapterArrayController загружать: [chapterArrayController fetchWithRequest: nil merge: NO error: nil]; и у меня есть главаArrayController, связанный с объектом NSArrayController с привязками в обоих наконечниках. NSArray a = [chapterArrayController assemblyObjects] int b = [a count]; NSLog (@ "элементы в массиве:% d", b); ИНТ б выше 0 каждый раз, и если я пытаюсь сделать это: NSObject * о = [chapterArrayController newObject]; NSLog (@ "Где находится объект:% @", o); NSLog будет записывать «null». –

+1

Если chapterArrayController равен нулю, когда fetchWithRequest: merge: error: вызывается, ничего не произойдет. Я предполагаю, что chapterArrayController - это IBAutlet ivar, да? Попробуйте поставить: NSLog (@ "controller:% @", chapterArrayController); сразу после запроса на выборку. Я думаю, что он вернет ноль. Можете ли вы показать код, загружающий второй наконечник (тот, на который ссылается главаArrayController)? – MyztikJenz

+0

MyztikJenz: Если 'chapterArrayController' были' nil', просить его для 'builtObjects' возвращать' nil'. Запрашивание 'nil' для' count' вернет 0. Он говорит, что 'count' возвращает ненулевое значение; поэтому 'chapterArrayController' не' nil'. –

0
[[self alloc] standAloneTestArrayControllers]; 

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

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

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

If I call the standAloneTestArrayControllers from JBAddChapter's IBAction, everything works fine. If I call that same method from AppController using the a factory method in JBAddChapter, I the array controllers are nil.

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

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

So, why would the array controllers be returning nil from one method, but not the other?

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

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

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

0

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

+0

Знаешь, я видел это раньше. Единственный другой вариант, который я нашел, который работал (и только некоторое время), - это сохранить nibs как xibs или наоборот. Ошибка в IB? Я никогда не мог достоверно воспроизвести его. – MyztikJenz

Смежные вопросы