我有一个控制一个窗口的类,另一个控制同一个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
答案 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