1

我将发布使用自动释放著名方法 stringByAppendingString 的示例方法的缺点 3 变体。(xcode 4.6.2.IOS 项目中的非弧示例项目)

示例块 1:没有返回任何内容。只是一个奇怪的指向没有内容。但不是 null。
示例块 2:也不返回任何内容!。
样本块 3:返回 A1A2A3。正如预期的那样,但我认为它有泄漏。

我的问题是:
a)示例方法 1 在 MAC 项目中按预期工作。但在 IOS 项目中没有。
b) 样品块 3 - 是否包含泄漏?
c) 查看示例块 2 中的注释。word_ 变为 A1,A1A2 并且什么都没有。为什么?
d)你会用不同的方式编写你自己的相同方法的代码吗?我正在寻找安全的标准方法。

谢谢。


样品块 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_;
}

样品块 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_;
}

样板 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.
}


我的回答:只是因为我没有做错任何事情。并且通过调试过程步骤非常清晰地收集了变量值。

但不知何故,它在清理项目后得到了解决。希望这可以为某人节省几个小时。或者不知道内存芯片地址可能出了什么问题。

4

3 回答 3

4

第一种方法是正确进行内存管理的唯一方法。第二个泄漏两个,第三个泄漏三个 NSString 实例。如果您没有从第一种方法中获得字符串“A1A2A3”,则错误位于该方法之外。

对于您发送的每条保留消息,您还必须以相同的方法发送释放或自动释放消息,除非您的方法名称以 alloc 或 copy 开头。在这种情况下,调用者需要释放返回的对象。

于 2013-07-08T21:34:58.727 回答
3

a) 哪个样品块 3 - 包括泄漏?

-retain您的样品中的每一次使用都是出乎意料的,并且可能会导致泄漏。

b) 查看 Sample Block.word_ 中的注释变成 A1,A1A2 而什么都没有。为什么?

请仔细检查。

c)你会用不同的方式为你自己编码相同的方法吗?我正在寻找安全的标准方法。

您可以使用可变字符串,例如:

- (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];
}

或格式字符串:

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

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

然后根据您的实际输入进行混合和匹配。

于 2013-07-08T21:46:27.533 回答
2

第二个和第三个块包含泄漏。一般规则是你保留你想拥有的东西,当你不再需要它时释放它。第一个块非常好:您返回一个自动释放的字符串,如果调用者想要拥有它,它将由调用者保留,否则,它将在将被清理的第一个自动释放池中释放。

在第二个块中,您正在执行此操作:

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

字符串@"A1A2" 的保留计数为 2,在下一次自动释放池耗尽时,它的保留计数为 1,但您丢失了对它的任何引用,因此这是泄漏。至于保留字符串@“A1A2A3”,那也是不正确的:调用者将决定是否要保留它。出于同样的原因,第三个块是不正确的。

于 2013-07-08T21:36:17.177 回答