Класс какао, не отображающий данные в NSWindow

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

В первом классе I выделений и init второй класс, затем передайте некоторую информацию ему. Во втором классе это отображает те данные в табличном представлении.
Да, в .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
задан outis 4 May 2010 в 20:50
поделиться

1 ответ

Проблемы в вашем коде многочисленны.

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

window.isVisible = YES

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

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

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

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

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

- initWithVoteCount:user:text:

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

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

Конечно, в этом случае вы также должны добавить метод -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
2
ответ дан 3 September 2019 в 00:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: