Класс какао не отображает данные в NSWindow - PullRequest
1 голос
/ 04 мая 2010

У меня есть один класс, который управляет одним окном, и другой класс, который управляет другим окном в том же XIB, однако второе окно никогда не отображает то, что должно.

В первом классе я выделяю и инициирую второй класс, затем передаю ему некоторую информацию. Во втором классе эти данные отображаются в табличном представлении.
Да, в .xib у меня все соединения настроены правильно, я проверил четверной. Также код правильный, так же как и со связями, я проверил четверной.

Редактировать: и да, в массивах есть данные, а классы являются NSObjects.

Edit2: Я вроде нашел проблему. По какой-то причине массив заполнен содержимым, но он возвращает 0 в качестве счетчика.

Редактировать 9000:

Вот код:

Answer.h

#import <Cocoa/Cocoa.h>
@interface MSAnswerView : NSObject {
    IBOutlet NSWindow *window;
    NSArray *User;
    NSArray *Vote;
    NSArray *Text;
    IBOutlet NSTableView *view;
    IBOutlet NSTableColumn *voteCount;
    IBOutlet NSTableColumn *saidUser;
    IBOutlet NSTextView *body;
}
-(void)setUpWithVoteCount:(NSArray *)array User:(NSArray *)user Text:(NSArray *)text;

@property (nonatomic, retain) NSWindow *window;
@property (nonatomic, retain) NSTableView *view;
@property (nonatomic, retain) NSTableColumn *voteCount;
@property (nonatomic, retain) NSTableColumn *saidUser;
@property (nonatomic, retain) NSTextView *body;
@end

.m

#import "MSAnswerView.h"
@implementation MSAnswerView
@synthesize view;
@synthesize voteCount;
@synthesize saidUser;
@synthesize body;
@synthesize window;
-(void)awakeFromNib
{
    [view setTarget:self];
    [view setDoubleAction:@selector(bodydata)];
    [view reloadData];
}
-(void)setUpWithVoteCount:(NSArray *)array User:(NSArray *)user Text:(NSArray *)text
{
    Vote = array;
    User = user;
    Text = text;
    if (window.isVisible = YES) {
        [view reloadData];
        [view setNeedsDisplay];

    }
}
-(int)numberOfRowsInTableView:(NSTableView *)aTable
{
    return [User count];;
}

-(id)tableView:(NSTableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(int)aRow
{
    if (aCol == voteCount)
    {
        return [Vote objectAtIndex:aRow];
    }
    else if (aCol == saidUser)
    {
        return [User objectAtIndex:aRow];
    }
    else 
    {
        return nil;
    }


}

-(void)bodydata
{
    int index = [view selectedRow];
    [body setString:[Text objectAtIndex:index]];
}

@end

1 Ответ

2 голосов
/ 05 мая 2010

Проблем в вашем коде много.

Во-первых, это сравнение в -setUpWithVoteCount:User:Text: неверно:

window.isVisible = YES

Это должен быть оператор сравнения, ==, а не оператор присваивания =.

Во-вторых, вы неправильно называете свои ivars и методы. Переменные экземпляра (на самом деле переменные любого типа) должны начинаться со строчной буквы. Это должно отличить их от имен классов. Ознакомьтесь с Руководствами Apple по кодированию .

Я бы также предположил, что имя типа text является недопустимым именем для переменной, в которой хранится коллекция, например NSArray. Вместо этого вам следует назвать его как textItems, так что ясно, что переменная представляет коллекцию, а не одну строку.

Кроме того, сам класс плохо назван. Вы назвали это MSAnswerView, но это не вид, это какой-то тип оконного контроллера. По крайней мере, назовите это MSAnswerWindowController. Еще лучше было бы сделать его подклассом NSWindowController и сделать его Владельцем файла в его собственном кончике. Это стандартный шаблон для оконных контроллеров.

Ваш метод -setUpWithVoteCount:User:Text: действительно должен быть инициализатором:

- initWithVoteCount:user:text:

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

Однако основная проблема заключается в том, что вы не сохраняете значения, которые вы передаете в метод настройки. Это означает, что если ни один другой объект не сохранит ссылку на них, они исчезнут в какой-то неопределенной точке в будущем. Если вы получите к ним доступ позже, вы потерпите крах или, по крайней мере, получите неверные данные, что и происходит.

Конечно, вы также должны добавить метод -dealloc в этом случае, чтобы гарантировать, что вы отпустите объекты, когда закончите с ними.

Собрав все эти предложения вместе, ваш класс должен выглядеть примерно так:

MSAnswerWindowController.h

#import <Cocoa/Cocoa.h>

//subclass of NSWindowController
@interface MSAnswerWindowController : NSWindowController <NSTableViewDataSource>
{
    //renamed ivars
    NSArray *users;
    NSArray *voteCounts;
    NSArray *textItems;
    IBOutlet NSTableView *view;
    IBOutlet NSTableColumn *voteCount;
    IBOutlet NSTableColumn *saidUser;
    IBOutlet NSTextView *body;
}

//this is now an init method
- (id)initWithVoteCounts:(NSArray *)someVoteCounts users:(NSArray *)someUsers textItems:(NSArray *)items;

//accessors for the ivars
@property (nonatomic, copy) NSArray* users;
@property (nonatomic, copy) NSArray* voteCounts;
@property (nonatomic, copy) NSArray* textItems;

@property (nonatomic, retain) NSWindow *window;
@property (nonatomic, retain) NSTableView *view;
@property (nonatomic, retain) NSTableColumn *voteCount;
@property (nonatomic, retain) NSTableColumn *saidUser;
@property (nonatomic, retain) NSTextView *body;
@end

MSAnswerWindowController.m

#import "MSAnswerWindowController.h"

@implementation MSAnswerWindowController

//implement the init method
- (id)initWithVoteCounts:(NSArray*)someVoteCounts users:(NSArray*)someUsers textItems:(NSArray*)items
{
    //this is an NSWindowController, so tell super to load the nib
    self = [super initWithWindowNibName:@"MSAnswerWindow"];
    if(self)
    {
        //copy all the arrays that are passed in
        //this means we hold a strong reference to them
        users      = [someUsers copy];
        voteCounts = [someVoteCounts copy];
        textItems  = [items copy];
    }
    return self;
}

//make sure we deallocate the object when done
- (void)dealloc
{
    self.users      = nil;
    self.voteCounts = nil;
    self.textItems  = nil;
    [super dealloc];
}

//this is called when the window first loads
//we do initial window setup here
- (void)windowDidLoad
{
    [view setTarget:self];
    [view setDataSource:self];
    [view setDoubleAction:@selector(bodydata)];
}

//this is called when the view controller is asked to show its window
//we load the table here
- (IBAction)showWindow:(id)sender
{
    [super showWindow:sender];
    [view reloadData];
}

- (NSInteger)numberOfRowsInTableView:(NSTableView*)aTable
{
    return [users count];
}

- (id)tableView:(NSTableView*)aTable objectValueForTableColumn:(NSTableColumn*)aCol row:(NSInteger)aRow
{
    if (aCol == voteCount)
    {
        return [voteCounts objectAtIndex:aRow];
    }
    else if (aCol == saidUser)
    {
        return [users objectAtIndex:aRow];
    }
    return nil;
}

- (void)bodydata
{
    NSInteger index = [view selectedRow];
    [body setString:[textItems objectAtIndex:index]];
}

@synthesize users;
@synthesize voteCounts;
@synthesize textItems;
@synthesize view;
@synthesize voteCount;
@synthesize saidUser;
@synthesize body;
@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...