Objective c 为什么有两个ViewController实例以及如何修复它?
首先,我会给你一个简短的概述 我是Objective c 为什么有两个ViewController实例以及如何修复它?,objective-c,xcode,cocoa,Objective C,Xcode,Cocoa,首先,我会给你一个简短的概述 我是 创建新的cocoa项目 定制AppDelegate(请参见清单1) 将“自定义视图”添加到my MainMenu.xib 在项目中创建一个新的Cocoa类(NSViewController+XIB),称之为MyTableViewController* 向最近添加的ViewController添加“表视图”,如中所述 MyTableViewController的代码如清单2所示 现在来谈谈我的问题。 该表及其内容如下所示。 但是,如果我选择表中的一项并按下此子视
(iAction)action:(id)sender
),则输出中将显示(无索引)
(请参阅:selectedColumnIndexes
)。
经过一段时间的实验,我发现MyTableViewController类有两个实例
有人能解释一下为什么会有两种情况,并帮我解决这个问题吗
Thx
清单1:
// FILE: AppDelegate.h
#import <Cocoa/Cocoa.h>
@class MyTableViewController;
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (nonatomic, assign) NSViewController * currentViewController;
@property (nonatomic, strong) MyTableViewController * myTableViewController;
@property (weak) IBOutlet NSView *myview;
@end
// FILE: AppDelegate.m
#import "AppDelegate.h"
#import "MyTableViewController.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self changeViewController];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
return YES;
}
- (void)changeViewController
{
if ([self.currentViewController view] != nil) {
[[self.currentViewController view] removeFromSuperview];
}
switch (0) {
case 0:
default:
if (self.myTableViewController == nil) {
_myTableViewController = [[MyTableViewController alloc] initWithNibName:@"MyTableViewController" bundle:nil];
}
self.currentViewController = self.myTableViewController;
NSLog(@"EndView");
break;
}
[self.myview addSubview:[self.currentViewController view]];
[[self.currentViewController view] setFrame:[self.myview bounds]];
[self.currentViewController setRepresentedObject:[NSNumber numberWithUnsignedInteger:[[[self.currentViewController view] subviews] count]]];
[self didChangeValueForKey:@"viewController"];
NSLog(@"ViewController changed");
}
@end
//文件:AppDelegate.h
#进口
@类MyTableViewController;
@接口AppDelegate:NSObject
@属性(非原子,赋值)NSViewController*currentViewController;
@属性(非原子,强)MyTableViewController*MyTableViewController;
@属性(弱)IBMView*myview;
@结束
//文件:AppDelegate.m
#导入“AppDelegate.h”
#导入“MyTableViewController.h”
@接口AppDelegate()
@属性(弱)窗口*窗口;
@结束
@实现AppDelegate
-(无效)ApplicationIDFinishLaunching:(NSNotification*)通知{
[自动更改视图控制器];
}
-(无效)申请将终止:(NSNotification*)通知{
//在此处插入代码以删除应用程序
}
-(BOOL)应用程序应在最后一个窗口关闭后终止:(n应用程序*)应用程序{
返回YES;
}
-(无效)changeViewController
{
如果([self.currentViewController视图]!=nil){
[[self.currentViewController视图]从SuperView移除];
}
开关(0){
案例0:
违约:
if(self.myTableViewController==nil){
_myTableViewController=[[myTableViewController alloc]initWithNibName:@“myTableViewController”捆绑包:nil];
}
self.currentViewController=self.myTableViewController;
NSLog(@“EndView”);
打破
}
[self.myview addSubview:[self.currentViewController视图]];
[[self.currentViewController视图]设置帧:[self.myview边界]];
[self.currentViewController setRepresentedObject:[NSNumber numberWithUnsignedInteger:[[self.currentViewController视图]子视图]计数]];
[self-didChangeValueForKey:@“视图控制器”];
NSLog(@“视图控制器已更改”);
}
@结束
清单2:
// FILE: MyTableViewController.h
#import <Cocoa/Cocoa.h>
@interface MyTableViewController : NSViewController
@property (weak) IBOutlet NSTableView *tview;
- (IBAction)action:(id)sender;
@end
// FILE: MyTableViewController.m
#import "MyTableViewController.h"
#import "AppDelegate.h"
@interface MyTableViewController ()
@end
@implementation MyTableViewController
- (NSUInteger)numberOfRowsInTableView:(NSTableView *)tableViewObj {
return 2;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if ([tableView tableColumns][0] == tableColumn) {
return @"bla";
} else if ([tableView tableColumns][1] == tableColumn) {
return @"blub";
}
NSLog(@"dropped through tableColumn identifiers");
return NULL;
}
- (IBAction)action:(id)sender {
// selectedColumnIndexes
NSLog(@"%@", [self.tview selectedColumnIndexes]);
}
@end
//文件:MyTableViewController.h
#进口
@接口MyTableViewController:NSViewController
@属性(弱)ibnstableview*tview;
-(iAction)操作:(id)发送方;
@结束
//文件:MyTableViewController.m
#导入“MyTableViewController.h”
#导入“AppDelegate.h”
@接口MyTableViewController()
@结束
@MyTableViewController的实现
-(NSUTEGER)行数表格视图:(NSTableView*)表格视图OBJ{
返回2;
}
-(id)tableView:(NSTableView*)tableView对象值for tableColumn:(NSTableColumn*)tableColumn行:(NSInteger)行{
如果([tableView tableColumns][0]==tableColumn){
返回@“bla”;
}else if([tableView tableColumns][1]==tableColumn){
返回@“blub”;
}
NSLog(@“通过表列标识符删除”);
返回NULL;
}
-(iAction)操作:(id)发件人{
//选定的列索引
NSLog(@“%@,[self.tview selectedColumnIndexes]);
}
@结束
一个类的两个实例(当您只希望/想要一个实例时)可能是由于没有意识到xib文件中的对象本身就是该类的实际自动生成实例而导致的 您是否已将蓝色多维数据集拖到任何一个xib文件中,并将其类设置为视图控制器子类?如果你有,那么这将解释你看到的一个物体——苹果的机器为你创造它。第二个对象是您在
changeViewController
方法中以代码创建的对象
我得到的印象是,您只是试图创建一个窗口,其中包含一个NSTableView
,该窗口反过来从您自己的NSViewController
子类获取其数据。这是正确的吗?如果是这样,那么您应该删除第二个xib文件,而只使用在创建项目时为您创建的xib
简言之
MyTableViewController
李>
视图
选项拖动到表视图-必须确保拖动到的是表视图,而不是包含它的滚动视图或剪辑视图数据源
和委派
选项拖动到蓝色视图控制器多维数据集李>
标识符
,这有助于调试。在属性检查器中,这是还原ID。对NSTableView
实例和NSTableColumn
实例执行此操作。然后,在您的数据源方法中对它们进行一些日志记录-例如,作为此方法的第一个参数传递的表视图是否具有预期的标识符,wh