まず、この単純な質問でごめんなさい。しかし、私は何が起こっているのかを理解する必要があります。
出力は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];
}
何が起こっているのか、それを修正するにはどうすればよいですか?
[string lowercaseString]
呼び出しは、ローカル変数NSString
に割り当てるnewstring
オブジェクトを作成します。これは、stringVar
関数の外のchangeString
の値を変更しません。ポインタ自体は値で渡されます。
あなたが望むことをする1つの方法は、ポインターをポインターに渡すことです:
-(void) test
{
NSString *stringVar = @"UPPER CASE STRING";
[self changeString:&stringVar];
NSLog(@"value after changed : %@", stringVar);
}
-(void) changeString:(NSString**)string
{
*string = [*string lowercaseString];
}
[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
を使用することもできます。
私は上記の与えられた問題を参照し、あなたが間違いを手伝っています。
- (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
}
-(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];
}
string
はローカル変数(不変のNSStringへのポインター)であり、ローカル関数でstring
pointsが何を指しているかを変更しているだけですが、その値を返すと、その値は破棄されます。
文字列をパラメータとして渡し、関数から小文字の文字列を返すだけでよいでしょう。