在iOS中传递参数

时间:2012-10-21 03:43:33

标签: objective-c ios

我是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的变量,它有值,但它不是我从调用行传递的原始字典。 我做错了什么?

3 个答案:

答案 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)

dictionaryfname都是指针,它们由 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]]];