質問

I will post downside 3 variant of a sample method that uses autorelease famous method stringByAppendingString.(non-arc sample project in xcode 4.6.2.IOS project)

Sample Block 1: returns nothing.just a weird points to nothing.but not null.
Sample Block 2: returns nothing too!.
Sample Block 3: returns A1A2A3. as expected but I think it has leak.

My Questions are:
a) sample method 1 working as expected in MAC project.But not in IOS Project.
b) is sample block 3 - includes a leak ?
c) look at comments in Sample Block 2. word_ becomes A1,A1A2 and nothing.why ?
d) what would you code your-own of same method in a different ways?.Im looking for the safe standart method.

thanks.


SAMPLE BLOCK 1

-(NSString*)sampleMethod
{
    NSString *word_=@"";
    NSString *a1=@"A1";
    NSString *a2=@"A2";
    NSString *a3=@"A3";

    word_=[word_ stringByAppendingString:a1];// word_ is A1
    word_=[word_ stringByAppendingString:a2];// word is nothing but another pointer
    word_=[word_ stringByAppendingString:a3];// word is nothing too but pointer changed.
    return word_;
}

SAMPLE BLOCK 2

-(NSString*)sampleMethod
{
    NSString *word_=@"";
    NSString *a1=@"A1";
    NSString *a2=@"A2";
    NSString *a3=@"A3";

    word_=[word_ stringByAppendingString:a1];// word_ is A1
    word_=[[word_ stringByAppendingString:a2]retain];// word is A1A2
    word_=[[word_ stringByAppendingString:a3]retain];// word is nothing !
    return word_;
}

SAMPLE BLOCK 3

-(NSString*)sampleMethod
{
    NSString *word_=@"";
    NSString *a1=@"A1";
    NSString *a2=@"A2";
    NSString *a3=@"A3";

    word_=[[word_ stringByAppendingString:a1]retain];// word_ is A1
    word_=[[word_ stringByAppendingString:a2]retain];// word_ is A1A2
    word_=[[word_ stringByAppendingString:a3]retain];// word_ is A1A2A3
    return word_;//returns as expected but I think leaks method in this method.
}


My Answer :Just because I was nothing did wrong.and collected variable values by debug process steps very sharp.

but somehow it is solved after clean project.hope this may save hours for someone.or dont know maybe something went wrong in memory chip addresses.

役に立ちましたか?

解決

The first one is the only method that gets the memory management correct. The second one leaks two and the third one three NSString instances. If you don't get the string "A1A2A3" from the first method the error is somewhere outside that method.

For every retain message you send you also have to send a release or autorelease message in the same method, unless your method name starts with alloc or copy. In that case the caller needs to release the returned object.

他のヒント

a) which sample block 3 - includes a leak ?

Every use of -retain in your sample is unexpected and can introduce a leak.

b) look at comments in Sample Block.word_ becomes A1,A1A2 and nothing.why ?

Double check that, please.

c) what would you code your self of same method in a different ways?.Im looking for the safe standart method.

You could use a mutable string, for example:

- (NSString*)sampleMethod
{
    NSMutableString * word = NSMutableString.string;
    NSString *a1=@"A1";
    NSString *a2=@"A2";
    NSString *a3=@"A3";

    [word appendString:a1];
    [word appendString:a2];
    [word appendString:a3];

    return [NSString stringWithString:word];
}

or a format string:

- (NSString *)sampleMethod
{
    NSString *a1=@"A1";
    NSString *a2=@"A2";
    NSString *a3=@"A3";

    return [NSString stringWithFormat:@"%@%@%@", a1, a2, a3];
}

then just mix and match based on your actual inputs.

The second and third block contain a leak. The general rule is that you retain what you want to own, and you release it when you don't need it anymore. The first block is perfectly fine: you're returning an autoreleased string, which will be retained by the caller if he wants to own it, or if not, it will be released at the first autorelease pool that will be cleaned.

In the second block you're doing this:

word_=[[word_ stringByAppendingString:a2]retain];// word is A1A2
word_=[[word_ stringByAppendingString:a3]retain];// word is nothing !

The string @"A1A2" has a retain count of 2, it will have a retain count of 1 at the next autorelease pool drain, but you have lost any reference to it, so it's a leak. As for retaining the string @"A1A2A3", that's incorrect too: the caller will decide if he wants to retain it or not. The third block is incorrect for the same reasons.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top