3

我是 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"];

现在的问题是,在辅助方法结束时,我有一个名为字典的变量,它确实有值,但它不是我从调用行传递的原始字典。我究竟做错了什么?

4

3 回答 3

2

正如这里所解释的 -在目标 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传递。创建一个新的字典副本内容并返回它可能更有意义。

于 2012-10-21T04:00:36.463 回答
1

我猜问题是 data.archive 不是加载字典值的有效文件格式。如果要将值存储到文件中,然后将它们加载到字典中,我将在应用程序的主包中创建一个 .Plist 文件,您可以将值加载到字典中,如下所示:

NSString *dataFile = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
NSDictionary *dataDictionary = [[NSDictionary alloc] initWithContentsOfFile:dataFile];
于 2012-10-21T04:29:38.867 回答
1

dictionary并且fname都是指针,都是按传递的。就 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]]];
于 2012-10-21T05:17:51.717 回答