Objective c 在目标C中的设定器内保持和释放

Objective c 在目标C中的设定器内保持和释放,objective-c,ios,memory-management,Objective C,Ios,Memory Management,初学者问题: 我想了解一些基本的内存管理。如果我重写setter方法,那么下面的内容是否足以处理传入字符串的内存管理 - (void)setMyString:(NSString *)string { if (_myString != string){ [string retain]; [_myString release]; _myString = string; } } 我在这里的逻辑是,只要我们输入if语句,我就想获得传入字符

初学者问题:

我想了解一些基本的内存管理。如果我重写setter方法,那么下面的内容是否足以处理传入字符串的内存管理

- (void)setMyString:(NSString *)string
{
    if (_myString != string){
        [string retain];
        [_myString release];
        _myString = string;
    }
}
我在这里的逻辑是,只要我们输入if语句,我就想获得传入字符串的所有权,从而获得retain。接下来,我释放_myString对象。然后我将_myString对象设置为string对象。这是我困惑的根源:我是否需要在此时保留myString对象?或者,由于将其设置为字符串对象,我是否已经拥有对它的所有权


谢谢

除了最后的return\u myString语句之外,您所写的都是正确的

在字符串上调用retain时,将该实例的引用计数增加一。将string的值赋给_myString不会改变string和_myString现在指向的实际实例,因此第二个retain是不必要的,而且是不正确的

所有这些都表明,你所拥有的是多余的。if_myString!=字符串检查是指,如果使用已拥有的相同对象调用setter,则在有机会保留该对象之前,不希望释放该对象。在这种情况下,程序将崩溃,因为您释放它,它将被释放,但您保留对它的引用并继续使用它发送消息。由于对象是相同的,如果函数的参数与实例变量的当前值相同,则可以通过不执行任何操作来避免此问题。但是,在释放实例变量之前保留参数是完成完全相同任务的另一种方法

因此,您可以这样做:

- (void)setMyString:(NSString *)string
{
    if (_myString != string) {
        [_myString release];
        _myString = [string retain];
    }
}
或者这个:

- (void)setMyString:(NSString *)string
{
    [string retain];
    [_myString release];
    _myString = string;
}

我倾向于支持第一种方法,因为如果值相同,它会稍微快一点,并且在写出时会稍微简单一点。但事实上,这取决于个人偏好,你最初问题的形式也很好。

除了最后的return\u myString语句外,你所写的都是正确的

在字符串上调用retain时,将该实例的引用计数增加一。将string的值赋给_myString不会改变string和_myString现在指向的实际实例,因此第二个retain是不必要的,而且是不正确的

所有这些都表明,你所拥有的是多余的。if_myString!=字符串检查是指,如果使用已拥有的相同对象调用setter,则在有机会保留该对象之前,不希望释放该对象。在这种情况下,程序将崩溃,因为您释放它,它将被释放,但您保留对它的引用并继续使用它发送消息。由于对象是相同的,如果函数的参数与实例变量的当前值相同,则可以通过不执行任何操作来避免此问题。但是,在释放实例变量之前保留参数是完成完全相同任务的另一种方法

因此,您可以这样做:

- (void)setMyString:(NSString *)string
{
    if (_myString != string) {
        [_myString release];
        _myString = [string retain];
    }
}
或者这个:

- (void)setMyString:(NSString *)string
{
    [string retain];
    [_myString release];
    _myString = string;
}

我倾向于支持第一种方法,因为如果值相同,它会稍微快一点,并且在写出时会稍微简单一点。但事实上,这取决于个人偏好,您原始问题中的形式也很好。

还有一个简短的形式:

- (void)setFoo:(NSString *)aFoo {
  [_foo autorelease];
  _foo = [aFoo copy];
}
另外,来自google objective-c样式指南的提示:

永远不要只保留字符串。这样可以避免调用方在您不知情的情况下更改它。不要因为接受NSString而认为它实际上不是NSMutableString


还有一种简短的形式:

- (void)setFoo:(NSString *)aFoo {
  [_foo autorelease];
  _foo = [aFoo copy];
}
另外,来自google objective-c样式指南的提示:

永远不要只保留字符串。这样可以避免调用方在您不知情的情况下更改它。不要因为接受NSString而认为它实际上不是NSMutableString


不要再使用保留和释放。只要使用ARC,它将为您节省很多麻烦。您不必处理内存泄漏、编写大量保留/释放等问题


它将与iOS 4配合使用,并且由于当前的iOS版本是6,因此现在使用ARC比去年ARC是新版本时要好。

不再使用retain And release。只要使用ARC,它将为您节省很多麻烦。您不必处理内存泄漏、编写大量保留/释放等问题


它将与iOS 4配合使用,并且由于当前的iOS版本是6,因此现在使用ARC比去年ARC是新版本时更好。

该方法被宣布为无效。你为什么要退货?哎呀,打字错误。谢谢我修好了你的逻辑是准确的。它应该可以正常工作:您通常希望复制NSString而不是保留它们,原因如下:您可能还希望比较字符串:![[u myString IsequalString:string]而不是

比较指针:if _myString!=该方法被声明为无效。你为什么要退货?哎呀,打字错误。谢谢我修好了你的逻辑是准确的。它应该可以正常工作:您通常希望复制NSString而不是保留它们,原因如下:您可能还希望比较字符串:![\u myString IsequalString:string]而不是比较指针:if\u myString!=第一个例子是错误的。如果确实使用ARC,则不能使用retain。如果不使用ARC,将丢失[\u myString release]->内存泄漏。此示例不适用于ARC,并且在没有ARC的情况下会泄漏。第二,如果您使用setter和_myString==string,则其中一个代码可能会崩溃。谢谢您捕获了该示例。只是打字错误。请注意,如果您使用的是ARC,那么这些代码都不相关。在这种情况下,您只需执行_myString=string,ARC将负责正确、安全的内存管理调用。是的,在设置之前发布_myString。第二个就足够了,它不会崩溃。但它会在不需要时保留和释放。开销足够小,所以这不是一个真正的问题。@NeverBe,no,正如我在回答中所解释的,在释放字符串之前保留字符串_myString可以确保如果它们是相同的,那么实例不会被释放,而净引用计数是不变的。第一个示例是错误的。如果确实使用ARC,则不能使用retain。如果不使用ARC,将丢失[\u myString release]->内存泄漏。此示例不适用于ARC,并且在没有ARC的情况下会泄漏。第二,如果您使用setter和_myString==string,则其中一个代码可能会崩溃。谢谢您捕获了该示例。只是打字错误。请注意,如果您使用的是ARC,那么这些代码都不相关。在这种情况下,您只需执行_myString=string,ARC将负责正确、安全的内存管理调用。是的,在设置之前发布_myString。第二个就足够了,它不会崩溃。但它会在不需要时保留和释放。开销足够小,这不是一个真正的问题。@NeverBe,no,正如我在回答中解释的,在释放前保留字符串_myString确保如果它们相同,实例不会被释放,净引用计数不变。我同意,但我仍然有兴趣知道场景背后发生了什么我同意,但我仍然有兴趣知道这些场景背后发生了什么这不是一个好的做法-自动释放适用于返回不需要保留但调用方可能保留的对象的情况。不要在可以使用-release的时候使用它。这是官方的google objective c样式指南的一部分google不是objective-c编码样式的权威。在这种情况下使用-autorelease是一种浪费。。。所以,给我看一份权威文件,上面说这是一种不好的做法:不需要权威:仔细想想。与排队发送延迟消息相比,发送即时消息的成本是多少?这不是一个好的做法-自动释放适用于返回不需要保留但调用方可能保留的对象的情况。不要在可以使用-release的时候使用它。这是官方的google objective c样式指南的一部分google不是objective-c编码样式的权威。在这种情况下使用-autorelease是一种浪费。。。所以,给我看一份权威文件,上面说这是一种不好的做法:不需要权威:仔细想想。与排队发送延迟消息相比,发送即时消息的成本是多少?