2013-07-08 31 views
1

我会后,使用自动释放著名方法stringByAppendingString的样品的方法的缺点3变体(在Xcode 4.6.2.IOS项目非弧样本项目)stringByAppendingString并保留困境

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

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

谢谢。


样品块1

-(NSString*)sampleMethod 
{ 
    NSString *[email protected]""; 
    NSString *[email protected]"A1"; 
    NSString *[email protected]"A2"; 
    NSString *[email protected]"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 *[email protected]""; 
    NSString *[email protected]"A1"; 
    NSString *[email protected]"A2"; 
    NSString *[email protected]"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 *[email protected]""; 
    NSString *[email protected]"A1"; 
    NSString *[email protected]"A2"; 
    NSString *[email protected]"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. 
} 


我的答案:只是因为我什么都没做错。通过调试过程步骤收集变量值非常尖锐。

但不知何故,它解决了干净的project.hope这可能为他人节省几个小时。或不知道也许在内存芯片地址出了问题。

+1

如果你的代码没有做它应该做的事情放在断点并检查它,如果你看到它没有做代码说什么,是时候清理了。 –

+2

仅供参考,写这个的惯用方式是'NSString * word_ = [NSString stringWithFormat:@“%@%@%@”,a1,a2,a3]'。 – Chuck

+0

我认为这只是了解内存管理如何工作的一个例子。否则,他可以返回@“A1A2A3”。 –

回答

4

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

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

+0

示例块1在Mac App中返回A1A2A3。但在IOS中的空字符串(返回一个奇怪的指针,不会给出任何错误,但像一个空字符串) –

+0

好。我确定这不是一场噩梦。我只是一个一个收集数据并在这里报告。经过清理工程后,第一块样板块按预期工作,我无法确定原因。 –

2

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

在第二块你这样做:

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

字符串@“A1A2”已经2的保留计数,它会在下次自动释放池漏极保留1计数,但你已经失去了任何参考,所以这是一个泄漏。至于保留字符串@“A1A2A3”,这也是不正确的:调用者将决定是否要保留它。由于相同的原因,第三个块不正确。

+0

我觉得同样的:样本块1是它应该的。 但是样本块1;没有返回任何问题。 –

+0

你的意思是什么都没有返回? –

+0

示例块1在Mac App中返回A1A2A3。但在iOS中的空格字符串(返回一个奇怪的指针,不会给出任何错误,但像一个空字符串) –

3

a)哪个样本块3 - 包含泄漏?

样品中每次使用-retain都是意料之外的,可能会引入泄漏。

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

仔细检查一下,请。

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

你可以使用一个可变的字符串,例如:

- (NSString*)sampleMethod 
{ 
    NSMutableString * word = NSMutableString.string; 
    NSString *[email protected]"A1"; 
    NSString *[email protected]"A2"; 
    NSString *[email protected]"A3"; 

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

    return [NSString stringWithString:word]; 
} 

或格式字符串:

- (NSString *)sampleMethod 
{ 
    NSString *[email protected]"A1"; 
    NSString *[email protected]"A2"; 
    NSString *[email protected]"A3"; 

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

然后就混合,并根据您的实际投入比赛。

+1

NSMutableString.string在逻辑上是不正确的:点符号应该只用于访问属性。 –

+1

@RamyAlZuhouri这真的只是你的首选编码习惯 - 没有不正确或不合逻辑的。 – justin

+1

@RamyAlZuhouri:苹果公司的文档从来没有这样说过,而且实际上提供了相反的例子(例如'array.count')。点语法是调用访问器的一般方法,无论它们是否是声明属性的一部分。如果它是一个访问器,使用点符号在语义上是正确的。 – Chuck