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

Objective-C,将变量值分配给plist字符串,objective-c,macos,plist,nsmutabledictionary,Objective C,Macos,Plist,Nsmutabledictionary,我有一个.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>

我有一个
.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
(无需特别在代码中执行),因此,对于
variable1
世界,来自
.plist
的值最终为
Hello
用于
变量2

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

[myDict setObject:variable1 forKey:@"key1"];
这正是我想要避免的。显然,“变量”仅仅是
.plist
中的字符串,obj-c不想给它们分配代码中变量的值。所以问题是我可以从代码中为它们赋值(比如
variable1
),还是不让它们成为字符串?或者这是不可能的

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

所以问题是我可以从代码中给它们赋值(比如variable1),还是不让它们变成字符串

很多方法,但是

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

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

显然,“变量”仅仅是.plist中的字符串,obj-c不想给它们分配代码中变量的值

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

让我们看看我们是否可以帮助您,而不必上一堂关于程序设计的长课。首先,我们将坚持使用您的字典的PLIST(稍后给出您的建议:<代码>变量<1/代码>,您可能希望考虑使用您自己的XML)。 其次,我们将假设当“变量”在字典中用作值时,它将始终是整个值而不是它的一部分,例如,您将永远不会有类似于
key1的内容变量的值是:variable1
,并期望替换
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
就像你的代码一样

现在,不用声明两个变量,
variable1
variable2
,您可以使用一个字典,其中键是变量名:

NSDictionary *variables = @{ @"variable1": @"Hello",
                             @"variable2": @"World!"
                           };
这表示与两个不同变量相同的信息,但至关重要的是,变量名只是字符串,正如您已经观察到的,plist包含字符串–因此现在我们遇到了字符串替换而不是变量替换的问题。为了进行字符串替换,我们使用:

  • 字典中的键查找,例如上面的
    myDict[@“key1”]
    ,如果字典中不存在键,则返回
    nil
  • 表达式
    ?:
    的计算结果为
    的值,如果该值不是
    nil
    ,则它的计算结果为
    (这是条件表达式的一个缩略,您可以查找。)
因此,如果我们将索引结果分配到plist to变量中:

NSString *rawKeyValue = myDict[@"key1"];
然后在我们的
变量
字典中查找该值:

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: Hello
为每个查找执行这些额外的步骤是重复和乏味的,编程有一个解决方案:定义一个方法来封装它,并避免使用中间变量。以下是一种可能的方法:

- (NSString *)substitute:(NSDictionary *)variables in:(NSString *)value
{
   return variables[value] ?: value;
}
定义后,第一个
NSLog
变为:

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

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

可能在info.plist中编写不是个好主意,也不起作用,因为您正试图将字典写入应用程序包中的.plist文件,该文件是只读的。因此,它将不起作用,而且即使您以其他方式完成,也会有更多的拒绝机会。顺便说一句,为什么只有信息列表?我的意思是为什么你不能用其他方式,比如NSUserDefault和SQLite@DhavalRaval:我实际上不想写入应用程序
.plist
,而是使用
.plist
作为应用程序使用的词典的模板。该应用程序也是一个内部工具,不在AppStore中提供。这是一个很好的信息,非常感谢您花时间解释它。