Cocoa类不在NSWindow中显示数据

时间:2010-05-04 01:07:09

标签: cocoa class nstableview

我有一个控制一个窗口的类,另一个控制同一个xib中不同窗口的类,但是,第二个窗口永远不会显示它应该显示的内容。

在第一个类中,我分配并初始化第二个类,然后将一些信息传递给它。在第二个类中,它在表格视图中显示该数据 是的,在.xib中,我已经正确设置了所有连接,我已经检查了四倍。此外,代码是正确的,与连接相同,我已经检查了四倍。

编辑:是的,数组中有数据,类是N​​SObjects。

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 个答案:

答案 0 :(得分:2)

您的代码中的问题很多。

首先,-setUpWithVoteCount:User:Text:中的这种比较不正确:

window.isVisible = YES

那应该是比较运算符,==而不是赋值运算符=

其次,您正在错误地命名您的ivars和方法。实例变量(实际上是任何类型的变量)应以小写字母开头。这是为了将它们与类名区分开来。查看Apple coding guidelines

我还建议像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