我正在尝试将连接到myViewController的NSTextView的内容更新为作为子类myViewController的文件所有者的引用插座。
当我从按钮使用IBAction或使用控制器的Stage
方法时,我可以更新文本。但是,当我尝试从另一个类(在此示例中称为viewDidLoad
)运行该方法时,它会运行该方法,但textview不会更改。
myViewController.h:
anotherViewController
myViewController.m:
#import <Cocoa/Cocoa.h>
#import "anotherViewController.h"
@interface myViewController : NSViewController { }
@property (unsafe_unretained) IBOutlet NSTextView *outText;
@property (weak) IBOutlet NSButton *updateMeButton;
- (void)updateTextView:(NSString *)argText;
- (void)updateTextViewWithoutArg;
@end
在 anotherViewController.m 中,有所有相关的导入,我称之为:
#import "myViewController.h"
@interface myViewController ()
@end
@implementation myViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.outText.string = @"I work successfully";
}
- (IBAction)updateMeButton:(id)sender {
self.outText.string = @"I am updated text! I also work!";
}
- (void)updateTextView:(NSString *)argText {
self.outText.string = @"I don't make it to the NSTextView :(";
NSLog(@"Should have updated text view");
}
- (void)updateTextViewWithoutArg {
self.outText.string = @"I don't make it to the NSTextView :(";
NSLog(@"Should have updated text view");
}
@end
什么都没发生。该方法运行并记录它应该已更新,但没有文本更新。我尝试了很多不同的方法,包括textstorage和scrollrange方法,它们都在已经工作的部分工作,但是在不工作的部分没有区别。
我也尝试过只是为了好玩:
myViewController *viewtask = [[myViewController alloc] init];
[viewtask updateTextViewWithoutArg];
myViewController *viewtask;
[viewtask updateTextViewWithoutArg];
_outText
[self.outText setString:@"string"];
同样,它们可以工作,但仅限于已经在工作的部分。
这应该很简单,但对我来说不合逻辑。在swift,我需要做的就是
[_outText setString:@"string"];
答案 0 :(得分:1)
您在Interface Builder中创建的视图是懒惰创建的,因此如果您在调用viewDidLoad
之前访问它们,则它们为nil
。
如果您的情况,请致电
myViewController *viewtask = [[myViewController alloc] init];
不会导致创建视图,因此在您调用
时[viewtask updateTextViewWithoutArg];
self.outText
是nil
。
您可以通过更新代码来了解这是发生的事情:
- (void)updateTextView:(NSString *)argText {
NSAssert(self.outText != nil, @"self.outText must not be nil");
self.outText.string = @"I don't make it to the NSTextView :(";
NSLog(@"Should have updated text view");
}
你应该看到断言。
答案 1 :(得分:0)
我似乎通过使myViewController
成为单身类并使用sharedInstance
找到了解决方案。对于这个特殊应用程序,myViewController
是一个调试输出窗口,永远不需要放在另一个视图中。
我不会接受这个答案,因为这不是我确定的最好的答案。 可能仍然存在正确的解决方案,允许查找适用的myViewController
实例,并修改附加到其上的outText
属性。使用这个单例使得子类繁琐,因为如果我想能够解决10个视图控制器的问题,我必须为每个实例创建一个新类。
无论如何 - 我能够满足我的简单要求的方式:
<强> myViewController.h:强>
#import <Cocoa/Cocoa.h>
#import "anotherViewController.h"
@interface myViewController : NSViewController { }
@property (unsafe_unretained) IBOutlet NSTextView *outText;
@property (weak) IBOutlet NSButton *updateMeButton;
- (void)updateTextView:(NSString *)argText;
- (void)updateTextViewWithoutArg;
+ (id)sharedInstance;
@end
<强> myViewController.m:强>
#import "myViewController.h"
@interface myViewController ()
@end
@implementation myViewController
static myViewController *sharedInstance = nil;
+ (myViewController *)sharedInstance {
static myViewController *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[myViewController alloc] init];
});
return sharedInstance;
}
- (void)viewDidLoad {
[super viewDidLoad];
sharedInstance = self;
}
- (void)viewDidUnload {
sharedInstance = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.outText.string = @"I work successfully";
}
- (IBAction)updateMeButton:(id)sender {
sharedInstance.outText.string = @"Button Pressed";
}
- (void)updateTextView:(NSString *)argText {
sharedInstance.outText.string = argText;
}
- (void)updateTextViewWithoutArg {
sharedInstance.outText.string = @"I make it to the TextView now";
}
@end
现在,当我在 anotherViewController.m 中使用此代码时,它会更新正确的实例:
[myViewController.sharedInstance updateTextView:@"Updating with this string"];