macOS开发学习笔记 (11)保留用户默认设置

写一个小程序,用户输入信息后自动设置为默认,每一次启动程序都显示默认值。
macOS开发学习笔记 (11)保留用户默认设置_第1张图片
代码来自《cocoa入门第2版》(xcode3),以下是在xcode10下运行xcode3代码的差异。xcode3中新建工程后,需要自己建一个控制器对象;xcode10自动多创建一个viewcontroller;两者还有内存管理上自动引用计数的问题,xcode10要关闭自动引用计数模式才能编译通过alloc,retain等方法。

第一次:

按照书中代码和步骤,为了使用retain取消了自动引用计数。

声明控制器对象,声明插座变量和动作

@interface ViewController : NSViewController
{
    
    IBOutlet id bookField;
    IBOutlet id colorField;
    IBOutlet id foodField;
    IBOutlet id cityField;
    NSUserDefaults * prefs;
}
-(IBAction)textFieldChanged:(id)sender;
@end

控制器的实现中加入以下代码


-(id)init
{
    [super init];
    NSMutableDictionary * defaultPrefs = [NSMutableDictionary dictionary];
    
    [defaultPrefs setObject:@"Learning" forKey:@"Fbook"];
    [defaultPrefs setObject:@"Shenzhen" forKey:@"Fcity"];
    [defaultPrefs setObject:@"red" forKey:@"Fcolor"];
    [defaultPrefs setObject:@"milk" forKey:@"Ffood"];
    
    prefs = [[NSUserDefaults standardUserDefaults] retain];
    [prefs registerDefaults:defaultPrefs];
    return self;
}
-(void)dealloc
{
    [prefs release];
    [super dealloc];
}
-(void)awakeFromNib
{
    //此处抛出错误
    [bookField setStringValue:[prefs stringForKey:@"Fbook"]];
    [cityField setStringValue:[prefs stringForKey:@"Fcity"]];
    [colorField setStringValue:[prefs stringForKey:@"Fcolor"]];
    [foodField setStringValue:[prefs stringForKey:@"Ffood"]];
}

运行时抛出错误
Thread 1: signal SIGABRT
网上找了一些解答,逐一尝试,无法解决。回想起viewDidLoad类似init,awakeFromNib都是程序运行前自动加载,就把代码塞到viewDidLoad方法里

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    NSMutableDictionary * defaultPrefs = [NSMutableDictionary dictionary];
    
    [defaultPrefs setObject:@"Learning" forKey:@"Fbook"];
    [defaultPrefs setObject:@"Shenzhen" forKey:@"Fcity"];
    [defaultPrefs setObject:@"red" forKey:@"Fcolor"];
    [defaultPrefs setObject:@"milk" forKey:@"Ffood"];
    
    //必须保留引用,使其他对象能使用它
    prefs = [[NSUserDefaults standardUserDefaults] retain];
    [prefs registerDefaults:defaultPrefs];
    
    [bookField setStringValue:[prefs stringForKey:@"Fbook"]];
    [cityField setStringValue:[prefs stringForKey:@"Fcity"]];
    [colorField setStringValue:[prefs stringForKey:@"Fcolor"]];
    [foodField setStringValue:[prefs stringForKey:@"Ffood"]];
}

补充完textFieldChange方法

-(IBAction)textFieldChanged:(id)sender
{
    if(sender == bookField){
        [prefs setObject:[bookField stringValue] forKey:@"Fbook"];
    }else if(sender == cityField){
        [prefs setObject:[cityField stringValue] forKey:@"Fcity"];
    }else if(sender == colorField){
        [prefs setObject:[colorField stringValue] forKey:@"Fcolor"];
    }else if(sender == foodField){
        [prefs setObject:[foodField stringValue] forKey:@"Ffood"];
    }
}

2.1命令行访问程序的默认值

defaults read vtech.Favorites
vtech.Favorites是工程general配置的identity里的bundle identifier这一条属性
defaults write vtech.Favorites Fcity “beijing”;


运行一下,发现默认值已改变
open …/Favorites.app
(…是省略的路径,在build文件夹里)

2.2使用唯一应用程序标识

直接在Xcode里修改工程的应用程序标识:工程->目标->info->bundle identifier
比如改成com.test

同样地在命令行里执行,把vtech.Favorites改成com.test,能查看程序默认值。

注意,修改项目环境变量后,运行一遍才生效。

你可能感兴趣的:(MacOS)