我是iOS新手,按值或引用传递参数(我来自Java / .NEt背景)让我感到困惑。 你看我有一种实用程序/帮助器方法,我传递给它一个NSMutableDictionary,然后一个文件位置,并要求它从文件到我发送它的字典中的非执行数据。 这是辅助方法:
- (void)loadData:(NSMutableDictionary *)dictionary fromFile:(NSString *)fname {
dictionary = [ NSKeyedUnarchiver unarchiveObjectWithFile : [ self getFilePath:fname ] ] ;
if ( [dictionary.allKeys count] < 1 ) {
NSLog(@"Couldn't load file %@ ", fname);
} else {
NSLog(@"Loaded data from file %@ successfully", fname );
}
}
现在我在以下代码行中调用此方法
[ loadData: dataDict fromFile:@"data.archive"];
现在的问题是,在帮助器方法结束时,我有一个名为dictionary的变量,它有值,但它不是我从调用行传递的原始字典。 我做错了什么?
答案 0 :(得分:2)
正如此处所解释的那样 - Passing arguments by value or by reference in objective C - 在目标c中,参数通过值传递,因此对参数进行的修改是修改值而不是传入的引用的实际值。
如果您想修改字典,则应在其前面添加**
以传递参考值,然后使用*
进行访问。
- (void)loadData:(NSMutableDictionary**)dictionary fromFile:(NSString*)fname {
{
*dictionary = [NSKeyedUnarchiver unarchiveObjectWithFile:[self getFilePath:fname]];
if ([*dictionary.allKeys count] < 1) {
NSLog(@"Couldn't load file %@ ", fname);
}
else {
NSLog(@"Loaded data from file %@ successfully", fname);
}
}
注意:这种指针解除引用有点时髦,可能仅限于**Error
传递。创建新的字典副本内容并返回它可能更有意义。
答案 1 :(得分:1)
我猜测问题是data.archive不是加载字典值的有效文件格式。如果要将值存储到文件中,然后将它们加载到字典中,我将在应用程序的主包中创建.Plist文件,您可以将值加载到字典中,如下所示:
NSString *dataFile = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
NSDictionary *dataDictionary = [[NSDictionary alloc] initWithContentsOfFile:dataFile];
答案 2 :(得分:1)
dictionary
和fname
都是指针,它们由 value 传递。就C构造而言,你会称之为引用。但是,该语言允许您将该参数重新分配给新指针。
所以如果我们更详细地看一下这个:
- (void)loadData:(NSMutableDictionary *)dictionary << a pointer variable local to the method
fromFile:(NSString *)fname
{
dictionary = << oops! assigned that pointer parameter to a different instance
[NSKeyedUnarchiver unarchiveObjectWithFile:[self getFilePath:fname]];
if ([dictionary.allKeys count] < 1 ) { << new instance will be messaged, NOT the object originally passed by parameter
并介绍如何实现您的目标:
[dictionary setDictionary:[NSKeyedUnarchiver unarchiveObjectWithFile:[self getFilePath:fname]]];