0

I've a question about NSMutablearray addobject, I think it's about object lifecycle. Searched but not got answer.

Here's the code:

    NSMutableString *str1 = [[NSMutableString alloc]init] ;
    NSMutableArray *arr1 = [[NSMutableArray alloc]init] ;
    for (int i=0 ;i<3 ;i++) {
        str1 =[NSMutableString stringWithFormat:@"%ld",(random() % 100) ] ;
        [arr1 addObject:str1] ;
        NSLog(@"arr1 inside loop:%@",arr1) ;
        [str1 setString:@""] ;    }
    NSLog(@"arr1 outside loop:%@",arr1) ;

    NSMutableString *str2 = [[NSMutableString alloc]init] ;
    NSMutableArray *arr2 = [[NSMutableArray alloc]init] ;
    for (int i=0 ;i<3 ;i++) {
        str2 =[NSMutableString stringWithFormat:@"%ld",(random() % 100) ] ;
        [arr2 addObject:str2] ;        }
    [str2 setString:@"abc"] ;
    NSLog(@"arr1:%@",arr2) ;

I expect that arr1 & arr2 both include 3 random number objects. but the real output is:

arr1 inside loop:(
    83
)
arr1 inside loop:(
    "",
    86
)
arr1 inside loop:(
    "",
    "",
    77
)
arr1 outside loop:(
    "",
    "",
    ""
)
arr2:(
    15,
    93,
    abc
)

Q1: Arr1, why the added objects changed to ""? (If the reason is all 3 objects are just 3 pointers and they point to the same object, then I have Q2 --)

Q2: Arr2, why the last object of arr2 is "abc" but the others not.

Thanks!

2 Answers 2

2

Q1:Arr1, why the added objects changed to ""?

Every time you used [NSMutableString stringWithFormat:@"%ld",(random() % 100) ] ; you created a new NSMutableString object and changed the pointer of str1 so it would point to that new object.

However, when you used [str1 setString:@""] ;, you changed str1's object value, so you changed the array object value as well, since [arr1 addObject:str1] ; adds the str1 pointer to the arr1 array only.

Q2:Arr2, why the last object of arr2 is "abc" but the others not.

This is your code with { and } in separated lines:

for (int i=0 ;i<3 ;i++) 
{
    str2 =[NSMutableString stringWithFormat:@"%ld",(random() % 100) ];
    [arr2 addObject:str2] ;
}
[str2 setString:@"abc"] ;
NSLog(@"arr1:%@",arr2) ;

You are creating new objects with [NSMutableString stringWithFormat:@"%ld",(random() % 100) ]; and changing the str2 pointer, adding its pointer to arr2 in [arr2 addObject:str2] ;.

After the for, you use [str2 setString:@"abc"], str2 is pointing to the last object that you created inside your for, which is the last item that you added to the array.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, vitormm! You're right! str = [NSMutableString stringwith ...] create a new object, and [str setString ...] just modifies the string value, that's the point! Now I modify the code [set string ...] to str = [NSMutableString stringWithFormat:@"%@",@""] , then the output is what I want!
0

[str1 setString:@""] modifies the string you have added to the array. In the first step you have a mutable string with value "83" but at the end of the iteration you are rewriting this same mutable string with an empty string "".

You can remove the line because you don't use the same instance again, actually, you don't need a mutable string at all:

for (int i = 0; i < 3; i++) {
   NSString *randomString = [NSString stringWithFormat:@"%ld", (random() % 100)] ;
   [arr1 addObject:randomString];
   NSLog(@"arr1 inside loop:%@", arr1);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.