【问题标题】:Objective C - Pass by value and pass by referenceObjective C - 按值传递和按引用传递
【发布时间】:2012-07-29 01:34:43
【问题描述】:

首先,很抱歉这个简单的问题。但我需要了解发生了什么。

我认为输出应该是 upper case string。但结果是 UPPER CASE STRING

- (void)test
{
     NSString *stringVar = @"UPPER CASE STRING";
     [self changeString:stringVar];
     NSLog(@"value after changed : %@", stringVar);
}

- (void)changeString:(NSString*)string
{
     string = [string lowercaseString];
}

发生了什么以及如何解决?

【问题讨论】:

    标签: ios objective-c string parameter-passing


    【解决方案1】:

    [string lowercaseString] 调用创建一个 NSString 对象,您将其分配给局部变量 string。这不会更改changeString 函数之外的stringVar 的值。指针本身是按值传递的。

    做你想做的事情的一种方法是将指针传递给指针:

    -(void) test
    {
         NSString *stringVar = @"UPPER CASE STRING";
         [self changeString:&stringVar];
         NSLog(@"value after changed : %@", stringVar);
    }
    
    -(void) changeString:(NSString**)string
    {
         *string = [*string lowercaseString];
    }
    

    【讨论】:

    • 只是为了确保即使在这种情况下,ARC 也会透明地处理内存,对吧?
    • 亲爱的 Greg,这意味着 Objective C 默认使用传值机制对吗?
    • @JoachimIsaksson:是的,ARC 正确地处理了内存管理(如果编译器无法弄清楚你在做什么,它会警告你)。
    • @charith: 是的,Objective-C 中参数传递的语义与 C 中相同。
    【解决方案2】:

    如果您查看对[NSString lowerCaseString] method 的引用,您可以看到它返回一个带有小写字符的新字符串:

    返回接收者的小写表示。

    - (NSString *)lowercaseString
    

    您的代码所做的只是用lowercaseString 调用的输出覆盖对输入字符串的引用,这没有任何效果。解决这个问题的最好方法是让你自己返回值,这使得方法更容易理解:

    -(void) test
    {
         NSString *stringVar = @"UPPER CASE STRING";
         stringVar = [self changeString:stringVar];
         NSLog(@"value after changed : %@", stringVar);
    }
    
    -(NSString *) changeString:(NSString*)string
    {
         string = [string lowercaseString];
         return string;
    }
    

    您需要了解NSString 是不可变的,因此除了重新分配引用之外,没有其他方法可以更改字符串的内容。但是,您可以改用 NSMutableString,它可以就地修改。

    【讨论】:

      【解决方案3】:

      我指的是上面给出的问题并帮助你解决错误。找到我的 cmets

      - (void)test
      {
           NSString *stringVar = @"UPPER CASE STRING";
           //StringVar is a pointer to integer class.let us assume the address the stringVar be 0x50 and the value it has be 0x100
           //So 0x100 has the string 
      
           [self changeString:stringVar];
           //above we are calling the method to lowercase and argument is stringVar
           //As the method is called we pass 0x100 in the argument as this is the memory where the value is kept
      
           NSLog(@"value after changed : %@", stringVar);
          //Our StringVar still points to 0x100 where the value is in upperString
      }
      
      - (void)changeString:(NSString*)string
      {
           string = [string lowercaseString];
          // Now operation performed on string returns a new value on suppose location 0x200
         //String parameter passed in argument is assigned the new value.But we never pass values as we pass only location under the hood
         //New parameter passed now points to new memory location 0x200
      
      }
      
      ---------------------------------------------------------------------------------
      With the new solution
      -(void) test
      {
           NSString *stringVar = @"UPPER CASE STRING";
           //let 0x50 be stringVar memorylocation pointing to 0x100 with above value
           [self changeString:&stringVar];
           //0x50 is passed in argument
           NSLog(@"value after changed : %@", stringVar);
           //On new location stored in address of stringVar it points to new string value
      }
      
      -(void) changeString:(NSString**)string
      {
           *string = [*string lowercaseString];
           //0x200 is new memory location received.*string gives the 0x100 location and hence the value
         //LHS is assigned to new location .On LHS you find *string which will be assigned 0x200
         //As string with location 0x50 is value 0x200 which will make it to point new      location where lowercase string exist
      }
      

      【讨论】:

        【解决方案4】:

        string 是一个局部变量(指向一个不可变的 NSString 的指针),您只是在局部函数中更改 stringpoints 的内容,但是当您返回时,它的值将被丢弃。

        您可能想要做的只是将字符串作为参数传递并从函数返回小写字符串。

        【讨论】:

          【解决方案5】:

          -(void) changeString:(NSString*)string中的字符串为局部变量,修改方法为返回值:

          -(void) test
          {
               NSString *stringVar = @"UPPER CASE STRING";
               stringVar =[self changeString:stringVar];
               NSLog(@"value after changed : %@", stringVar);
          }
          -(NSString *) changeString:(NSString*)string
          {
              return [string lowercaseString];
          }
          

          【讨论】:

          • 将 NSString 分配给 Void 方法是错误的,Void 方法不会返回值
          • 对不起,我的错,当然返回值是 'NSString*'
          猜你喜欢
          • 2014-04-08
          • 1970-01-01
          • 2015-06-12
          • 2023-03-07
          • 2014-08-23
          • 2015-05-23
          • 2023-03-02
          • 2011-05-08
          • 2014-04-04
          相关资源
          最近更新 更多