简体   繁体   English

如果我只有包含视图,如何设置NSTextView的stringValue?

[英]How do I set the stringValue of NSTextView if I only have the containing view?

Here is the question, hopefully easy to answer. 这是一个问题,希望很容易回答。

I'm making a class in which you give it an array of views and it saves all the elements inside it and is able to read them back. 我正在创建一个类,在该类中,您可以给它提供视图数组,并将其保存在其中的所有元素并能够读回它们。 I got the saving working by using NSArchiver class, but not the reading part. 我使用NSArchiver类节省了工作,但没有阅读部分。

@interface preferences : NSObject

- (void)savePreferences;
- (void)readPreferences;

@property (strong) NSMutableArray *theViews;

@end
 #import "preferences.h"

@implementation preferences
- (id)init {
    self = [super init];
    if (self) {
        _theViews = [[NSMutableArray alloc]init];
    }
    return self;
}

- (void)savePreferences{
    NSLog(@"Saving Preferences...");
    [NSKeyedArchiver archiveRootObject:_theViews toFile:@"preferences.xml"];
}

- (void)readPreferences{
    NSLog(@"Reading Preferences...");
    _theViews = [NSKeyedUnarchiver unarchiveObjectWithFile:@"preferences.xml"];
}

@end

The idea is I want an easy way to save preferences and recall them later. 我的想法是我想要一种简单的方法来保存首选项并稍后再调用它们。 I'm aware of NS_UserDefaults, and doing it manually by creating connections from interface builder to my code, but I have literally thousands of preferences that I would have to make connections for and save. 我知道NS_UserDefaults,并通过创建从接口构建器到我的代码的连接来手动执行此操作,但是实际上我有成千上万的首选项需要建立和保存连接。

So my goal is to create a class where I say something like... 所以我的目标是创建一个我说类似...的类

[preferences savePreferencesForViews:ArrayOfViews];//For Saving
[preferences readPreferencesForViews:ArrayOfViews];//For Reading

My plan was to set the identifier attribute in interface builder for every element. 我的计划是在接口构建器中为每个元素设置标识符属性。 Then to get a value out of it I would have a function cycle through every subview in the views until it found one who's identifier matched what I requested and I would inspect it's classtype to create a temporary variable of that and use that temporary variable of the class tpye to get the value out of it. 然后从中获取一个值,我将在视图中的每个子视图中进行一个功能循环,直到找到一个标识符与我所请求的匹配的标识符,然后我将检查它的类类型以创建该标识符的临时变量并使用该变量的类tpye以获得其价值。

For example, lets say the object inside of my NSView was an NSTextView with the stringValue of "hello world" 例如,假设我的NSView内的对象是带有stringValue为“ hello world”的NSTextView

Using the NSViews method subViews I return an array of all it's subviews, which would include the NSTextView mentioned above. 使用NSViews方法的子视图,我返回了所有子视图的数组,其中包括上面提到的NSTextView。

I can use the function from NSObject className to return the classname as @"NSTextView". 我可以使用NSObject className中的函数将类名返回为@“ NSTextView”。

Then I should be able to say... one of two things 那我应该可以说...两件事之一

   [subView setString:@"hey"];//compile error

or... 要么...

 NSTextView *temp = subView;
    [temp setString:@"test"];

That compiles but I get a warning (Incompatible pointer types initializing 'NSTextView *__strong' with an expression of type 'NSView *const __strong') 可以编译,但是我得到警告(使用“ NSView * const __strong”类型的表达式初始化“ NSTextView * __ strong”的不兼容指针类型)

When I run the program and attempt to run my routine it crashes and says -[NSTextField setString:]:unrecognized selector sent to an instance 0X101a0cfe0 当我运行程序并尝试运行我的例程时,它崩溃并说-[NSTextField setString:]:无法识别的选择器已发送到实例0X101a0cfe0

I have no idea what to do, help would be appreciated! 我不知道该怎么办,将不胜感激!

Hi there guys. 大家好 Here is the question, hopefully easy to answer. 这是一个问题,希望很容易回答。

I'm making a class in which you give it an array of views and it saves all the elements inside it and is able to read them back. 我正在创建一个类,在该类中,您可以给它提供视图数组,并将其保存在其中的所有元素并能够读回它们。 I got the saving working by using NSArchiver class, but not the reading part. 我使用NSArchiver类节省了工作,但没有阅读部分。

@interface preferences : NSObject

- (void)savePreferences;
- (void)readPreferences;

@property (strong) NSMutableArray *theViews;

@end
 #import "preferences.h"

@implementation preferences
- (id)init {
    self = [super init];
    if (self) {
        _theViews = [[NSMutableArray alloc]init];
    }
    return self;
}

- (void)savePreferences{
    NSLog(@"Saving Preferences...");
    [NSKeyedArchiver archiveRootObject:_theViews toFile:@"preferences.xml"];
}

- (void)readPreferences{
    NSLog(@"Reading Preferences...");
    _theViews = [NSKeyedUnarchiver unarchiveObjectWithFile:@"preferences.xml"];
}

@end

The idea is I want an easy way to save preferences and recall them later. 我的想法是我想要一种简单的方法来保存首选项并稍后再调用它们。 I'm aware of NS_UserDefaults, and doing it manually by creating connections from interface builder to my code, but I have literally thousands of preferences that I would have to make connections for and save. 我知道NS_UserDefaults,并通过创建从接口构建器到我的代码的连接来手动执行此操作,但是实际上我有成千上万的首选项需要建立和保存连接。

So my goal is to create a class where I say something like... 所以我的目标是创建一个我说类似...的类

[preferences savePreferencesForViews:ArrayOfViews];//For Saving
[preferences readPreferencesForViews:ArrayOfViews];//For Reading

My plan was to set the identifier attribute in interface builder for every element. 我的计划是在接口构建器中为每个元素设置标识符属性。 Then to get a value out of it I would have a function cycle through every subview in the views until it found one who's identifier matched what I requested and I would inspect it's classtype to create a temporary variable of that and use that temporary variable of the class tpye to get the value out of it. 然后从中获取一个值,我将在视图中的每个子视图中进行一个功能循环,直到找到一个标识符与我所请求的匹配的标识符,然后我将检查它的类类型以创建该标识符的临时变量并使用该变量的类tpye以获得其价值。

For example, lets say the object inside of my NSView was an NSTextView with the stringValue of "hello world" 例如,假设我的NSView内的对象是带有stringValue为“ hello world”的NSTextView

Using the NSViews method subViews I return an array of all it's subviews, which would include the NSTextView mentioned above. 使用NSViews方法的子视图,我返回了所有子视图的数组,其中包括上面提到的NSTextView。

I can use the function from NSObject className to return the classname as @"NSTextView". 我可以使用NSObject className中的函数将类名返回为@“ NSTextView”。

Then I should be able to say... one of two things 那我应该可以说...两件事之一

   [subView setString:@"hey"];//compile error

or... 要么...

 NSTextView *temp = subView;
    [temp setString:@"test"];

That compiles but I get a warning (Incompatible pointer types initializing 'NSTextView *__strong' with an expression of type 'NSView *const __strong') 可以编译,但是我得到警告(使用“ NSView * const __strong”类型的表达式初始化“ NSTextView * __ strong”的不兼容指针类型)

When I run the program and attempt to run my routine it crashes and says -[NSTextField setString:]:unrecognized selector sent to an instance 0X101a0cfe0 当我运行程序并尝试运行我的例程时,它崩溃并说-[NSTextField setString:]:无法识别的选择器已发送到实例0X101a0cfe0

I have no idea what to do, help would be appreciated! 我不知道该怎么办,将不胜感激!

My implementation of the interface is below 我的接口实现如下

@implementation appController

- (IBAction)savePreferences:(id)sender {
    NSLog(@"Save Button Pressed");

    //Create an instance of the preference class.
    preferences *PreferencesObject = [[preferences alloc]init];

    //Add the views we want to sve to the PreferenceObject.
    [[PreferencesObject theViews]addObject:_preferenceView];

    //Save the actual preferences now.
    [PreferencesObject savePreferences];

}
- (IBAction)loadPreferences:(id)sender {

    //Create an instance of the preference class.
    preferences __strong *PreferencesObject = [[preferences alloc]init];

    //Read the preferences into it's internal array.
    [PreferencesObject readPreferences];

    for(NSView __strong *view in [PreferencesObject theViews]){
        if([[view identifier]isEqualTo:[_preferenceView identifier]]){
            NSLog(@"View Match Found For PreferenceView, Setting...");


            for(NSView *subView in [_preferenceView subviews]){
                if([[subView identifier]isEqualTo:@"name"]){
                    NSLog(@"Attempting to set value of name control");
                    NSTextView *temp = subView;
                    [temp setString:@"test"];
                }
            }


        }
    }


}
@end

It seems like your views array contains text fields, not text views, maybe you made a binding error in IB. 看来您的视图数组包含文本字段,而不是文本视图,也许您在IB中发生了绑定错误。

A text field responds to setStringValue: , not to setString: . 文本字段响应setStringValue:,而不响应setString:。

Some tips 一些技巧

  • You can test the class belonging of an object; 您可以测试对象的类所属;
  • Provided that you are sure that a pointer points to an object of a certain class, you can cast the pointer. 只要确保指针指向某个类的对象,就可以强制转换指针。 In your case you would do a downcasting (from base class to subclass). 在您的情况下,您将进行向下转换(从基类到子类)。

So you would do something like: 因此,您将执行以下操作:

if ([ subview isKindOfClass: [NSTextView class]]) // until you fix that binding error or whatever, it will return NO
{
    NSTextView* temp= (NSTextView*) subview;
    [ temp setString: @"temp" ];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM