我有一个.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
我希望做的是让variable1
文件中的variable2
和.plist
使用代码中的variable1
和variable2
(没有在代码中专门这样做),所以从.plist
最终是Hello
的variable1
和World!
的variable2
。
显然,可以像这样分配它们:
[myDict setObject:variable1 forKey:@"key1"];
这正是我要避免的内容。显然,“变量”只是.plist
中的字符串,而obj-c则不认为从代码中为它们分配变量的值。所以问题是我可以为它们分配代码中的值(例如<variable>variable1</variable>
),还是不以某种方式使它们成为字符串?也许这只是不可能的。
注意:我不是程序员,所以请记住这一点,谢谢。
所以问题是我可以为它们分配代码中的值(例如variable1),还是不以某种方式使它们成为字符串?
很多方法,但是...
注意:我不是程序员,所以请记住这一点,谢谢。
这带来了明显的挑战!我们不知道您实际知道多少,也没有提出进行实际替代的尝试,等等。但是您确实做了一个很好的观察:
显然,“变量”只是.plist中的字符串,而obj-c则不认为从代码中为它们分配变量的值。
许多初学者,还有一些不是初学者,混淆了用作变量的name的字符序列variable1
和用作字符串的value的相同序列之间的区别–您正确地识别出这些是不同的东西。
让我们看看我们是否可以在没有大量程序设计课程的情况下为您提供帮助。首先,我们将坚持为字典使用plist(稍后,如果您建议<variable>variable1</variable>
,则不妨考虑使用自己的XML)。
第二,我们假设当在字典中将“变量”用作值时,它将始终是whole值,而不是其中的一部分,例如您将永远不会有<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
已添加到添加项中,并且包含您的plist。输出:
key1: variable1
key2: variable2
就像您的代码一样。
现在不用声明两个变量variable1
和variable2
,您可以使用字典,其中的键是变量名:
NSDictionary *variables = @{ @"variable1": @"Hello",
@"variable2": @"World!"
};
这代表与您的两个不同变量相同的信息,但至关重要的是变量名称仅为strings,并且正如您已经观察到的plist包含字符串一样-现在我们遇到了string替换问题而不是变量替换。要进行字符串替换,我们利用:
myDict[@"key1"]
返回nil
;<expr1> ?: <expr2>
,则表达式<expr1>
的计算结果为nil
的值,其他则为<expr2>
的计算值(这是条件表达式的收缩–您可以查看上。)因此,如果我们将索引到您的plist中的结果分配给变量:
NSString *rawKeyValue = myDict[@"key1"];
然后在我们的variables
字典中查找该值:
NSString *substitutedValue = variables[rawKeyValue];
然后,如果rawKeyValue
的值是您的“变量”名称之一(variable1
,variable2
),则substitutedValue
将是相应的值(Hello
,World!
)。如果rawKeyValue
不是变量名,则substitutedValue
将为nil
...
但是在第二种情况下您不希望nil
,您想要的是rawKeyValue
的值,您可以通过使用?:
运算符来获得它的值,该运算符将替换第一个NSLog()
的值:
NSString *rawKeyValue = myDict[@"key1"];
NSString *substitutedValue = variables[rawKeyValue] ?? rawKeyValue;
NSLog(@"key1: %@", substitutedValue);
将输出:
key1:你好
为每个查找执行这些额外的步骤是重复且乏味的,编程对此有一个解决方案:定义一种封装它的方法,并避免使用中间变量。这是一种可能的方法:
- (NSString *)substitute:(NSDictionary *)variables in:(NSString *)value
{
return variables[value] ?: value;
}
并且定义的第一个NSLog
变为:
NSLog(@"key1: %@", [self substitute:variables in:myDict[@"key1"]]);
希望能帮助您入门。但是,如果要编写程序,请花一些时间正确学习编程!