Objective-C,将变量值赋给plist字符串



我有一个.plist文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>key1</key>
<string>variable1</string>
<key>key2</key>
<array>
<string>foobar</string>
<string>variable2</string>
</array>
</dict>
</plist>

我的代码如下:

NSString *variable1 = @"Hello";
NSString *variable2 = @"World!";
NSMutableDictionary *myDict = [NSMutableDictionary dictionaryWithContentsOfFile:@"/path/to/file.plist"];
NSLog(@"key1: %@", [myDict valueForKey:@"key1"]);
NSLog(@"key2: %@", [[myDict valueForKey:@"key2"] objectAtIndex:1]);
// outputs
// key1: variable1
// key2: variable2

我希望.plist文件中的variable1variable2使用代码中的variable1variable2(而不是在代码中具体执行(,因此.plist中的值最终为variable1Hellovariable2World!

显然,这样分配它们是可能的:

[myDict setObject:variable1 forKey:@"key1"];

这正是我想要避免的。很明显,"变量"只是.plist中的字符串,obj-c不想给它们分配代码中变量的值。所以问题是,我能给它们分配代码中的值吗(比如<variable>variable1</variable>(,或者以某种方式不让它们成为字符串?或者这是不可能的。

注意:我不是程序员,所以请记住这一点,谢谢。

所以问题是,我可以给它们分配代码中的值(比如variable1(,还是不让它们成为字符串?

有很多方法,但是。。。

注意:我不是程序员,所以请记住这一点,谢谢。

这带来了明显的挑战!我们不知道你实际上知道多少,你没有尝试进行实际的替代,等等。但是你确实做了很好的观察:

很明显,"变量"只是.plist中的字符串,obj-c不想给它们分配代码中变量的值。

许多初学者和一些初学者混淆了用作变量的名称的字符序列variable1和用作字符串的值的相同序列之间的区别——您可以正确地识别出这是不同的东西。

让我们看看我们是否可以在不上太长程序设计课的情况下帮助您。首先,我们将坚持在字典中使用plist(稍后,考虑到<variable>variable1</variable>的建议,您可能希望考虑使用自己的XML(。

其次,我们将假设,当"变量"在字典中用作值时,它将始终是整个值,而不是它的一部分,例如,您永远不会有像<key>key1</key> <string>The value of the variable is: variable1</string>这样的东西,并期望variable1被替换。

我们首先修改您的代码,从应用程序包中读取plist,并使用现代Objective-C语法查找字典和数组值:

NSURL *sampleURL = [NSBundle.mainBundle URLForResource:@"sampleDictionary" withExtension:@"plist"];
NSMutableDictionary *myDict = [NSMutableDictionary dictionaryWithContentsOfURL:sampleURL];
NSLog(@"key1: %@", myDict[@"key1"]);    // dictionary lookup
NSLog(@"key2: %@", myDict[@"key2"][1]); // dictionary + array lookup

文件sampleDicitonary.plist已添加到add中,并包含您的plist。该输出:

key1: variable1
key2: variable2

就像你的代码一样。

现在,您不必声明两个变量variable1variable2,而是可以使用关键字为变量名的字典:

NSDictionary *variables = @{ @"variable1": @"Hello",
@"variable2": @"World!"
};

这表示与您的两个不同变量相同的信息,但至关重要的是,变量名只是字符串,并且正如您已经观察到的那样,您的plist包含字符串——所以现在我们遇到了串替换而不是变量替换

  • 在字典中查找关键字,例如上面的myDict[@"key1"],如果关键字不在字典中,则返回nil
  • 如果值不是nil,则表达式<expr1> ?: <expr2>的计算结果为<expr1>的值,其他表达式的计算结果则为<expr2>(这是条件表达式的缩写,您可以查找它(

因此,如果我们将索引到您的plist的结果分配给变量:

NSString *rawKeyValue = myDict[@"key1"];

然后在我们的variables字典中查找该值:

NSString *substitutedValue = variables[rawKeyValue];

则如果rawKeyValue的值为您的"变量"名称之一(variable1variable2(,则substitutedValue将是相应的值(HelloWorld!(。如果rawKeyValue不是变量名,则substitutedValue将是nil。。。

但在第二种情况下,您不需要nil,您需要rawKeyValue的值,您可以通过使用?:运算符来获得该值,该运算符替换了的第一个NSLog()

NSString *rawKeyValue = myDict[@"key1"];
NSString *substitutedValue = variables[rawKeyValue] ?? rawKeyValue;
NSLog(@"key1: %@", substitutedValue);

将输出:

key1: Hello

为每次查找执行这些额外的步骤是重复和乏味的,编程有一个解决方案:定义一个方法来封装它,并避免使用中间变量。这里有一种可能的方法:

- (NSString *)substitute:(NSDictionary *)variables in:(NSString *)value
{
return variables[value] ?: value;
}

并且利用所定义的第一CCD_ 41变为:

NSLog(@"key1: %@", [self substitute:variables in:myDict[@"key1"]]);

希望这能帮助你,让你开始。但是,如果你要写程序,一定要花时间好好学习编程!

最新更新