我在 Xcode 中创建了一个新的 Cocoa 应用程序项目,然后将一个 NSOutlineView 和一个 NSTextView 对象添加到窗口中。这两个对象被归类为 MyOutlineView 和 MyTextView。之后,我为他们做了两个出口并编写了如下代码。
我发现问题是应用程序在运行时有两个不同的 MyOutlineView 实例。工作(有效)大纲视图实例不等于 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 的相关方法。这似乎不自然。