gpt4 book ai didi

xcode - NSOutlineView 的 IBOutlet 未指向有效实例

转载 作者:行者123 更新时间:2023-12-03 16:58:22 24 4
gpt4 key购买 nike

我在 Xcode 中创建了一个新的 Cocoa 应用程序项目,然后将 NSOutlineView 和 NSTextView 对象添加到窗口上。这两个对象被子类化为 MyOutlineView 和 MyTextView。之后我为它们制作了两个导出并编写了如下代码。

我发现问题是应用程序在运行时有两个不同的 MyOutlineView 实例。工作(有效)大纲 View 实例不等于 myOutlineView 导出实例。我错过了什么?

//
// AppDelegate.h

#import <Cocoa/Cocoa.h>
#import "MyOutlineView.h"
#import "MyTextView.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet MyOutlineView *myOutlineView;
@property (unsafe_unretained) IBOutlet MyTextView *myTextView;

@end

//
// AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)n
{
NSLog(@"AppDelegate.myOutlineView(INVALID)::%@", _myOutlineView);
NSLog(@"AppDelegate.myTextView::%@", _myTextView);
}

@end

//
// MyOutlineView.h

#import <Cocoa/Cocoa.h>

@interface MyOutlineView : NSOutlineView <NSOutlineViewDataSource>;

@end

//
// MyOutlineView.m

#import "MyOutlineView.h"

@implementation MyOutlineView

- (id)initWithCoder:(NSCoder *)aDecoder
{
// This method is called first.
self = [super initWithCoder:aDecoder];
NSLog(@"MyOutlineView initWithCoder(INVALID)::%@", self);
return self;
}

- (id)initWithFrame:(NSRect)frame
{
// This method is also called but through a different instance with first one.
self = [super initWithFrame:frame];
NSLog(@"MyOutlineView initWithFrame(valid)::%@", self);
return self;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
NSLog(@"MyOutlineView data source delegate(valid)::%@", self);
return 0;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
return nil;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return NO;
}

@end

//
// MyTextView.h

#import <Cocoa/Cocoa.h>

@interface MyTextView : NSTextView

@end

//
// MyTextView.m

#import "MyTextView.h"

@implementation MyTextView

- (id)initWithCoder:(NSCoder *)aDecoder
{
// This method is called.
self = [super initWithCoder:aDecoder];
NSLog(@"MyTextView initWithCoder::%@", self);
return self;
}

- (id)initWithFrame:(NSRect)frame
{
// But this method is NOT called at all.
self = [super initWithFrame:frame];
NSLog(@"MyTextView initWithFrame::%@", self);
return self;
}

@end

输出:

MyTextView initWithCoder::                 [MyTextView: 0x10013be80]
MyOutlineView initWithCoder(INVALID):: [MyOutlineView: 0x10014bc90]
MyOutlineView initWithFrame(valid):: [MyOutlineView: 0x1001604a0]
MyOutlineView data source delegate(valid)::[MyOutlineView: 0x1001604a0]
AppDelegate.myOutlineView(INVALID):: [MyOutlineView: 0x10014bc90]
AppDelegate.myTextView:: [MyTextView: 0x10013be80]

因此,我必须输入“AppDelegate.myOutlineView = self;”进入 MyOutletView 的实现,无论它调用 AppDelegate 的相关方法。看起来不太自然。

最佳答案

Xcode 似乎不允许您将大纲 View 的委托(delegate)或数据源设置为自身。

所以我猜你正在做这样的事情:

enter image description here

也就是说:实例化自定义大纲 View 类的第二个副本。

这是此设置的输出:

2012-09-26 14:11:34.511 testproj[30255:403] -[MyOutlineView initWithCoder:]
2012-09-26 14:11:34.531 testproj[30255:403] -[MyOutlineView initWithFrame:]

通过删除“我的大纲 View ”的额外(突出显示的)实例,initWithFrame: 行将消失。

要使大纲 View 拥有自己的委托(delegate),请执行以下操作:

- (void) awakeFromNib {
self.delegate = self;
}

也就是说,委托(delegate)模式的要点是避免子类化的需要。如果您确实需要大纲 View 子类,请尝试直接重写 NSOutlineView/NSTableView 方法,而不是使用委托(delegate)协议(protocol)。

关于xcode - NSOutlineView 的 IBOutlet 未指向有效实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12600040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com