正确释放和保留NSString *

时间:2010-09-17 10:55:10

标签: iphone objective-c

大家好,我还是iPhone开发的新手,但对其他编程语言有很强的经验。让我脱掉头发的是Obj-C记忆管理和正确释放/保留。我知道这个概念,我知道“一旦我理解它会很容易”,但我还不是那里,这让我发疯。这里我有一个简单的代码,包含类和方法,只需将一个字符添加到现有的字符串中,该字符串被合成,因此用作类proprety ...例如,类称为myClass ...

myClas.h

@interface myClass : NSObject {
  @private 
  NSString* someCommonString;
}
@propery (retain, nonatomic) NSString* someCommonString;

myClass.m

...

@synthesize someCommonString;    

- (id) init 
{
   self = [super init];

   if(self)
   {
       someCommonString = [[NSString alloc] initWith String:@"one "];
   }
}

- (NSString*) appendString:(NSString*) stringToAdd
{
    NSString* result = [someCommonString stringByAppendingString: stringToAdd];
    return result;
}

- (void) doTheJob 
{
   NSString* test1 = @"two ";
   NSString* test2 = [[NSString alloc] initWithString: @"three "];
   NSString* test3 = [NSString stringWithFormat:@"four "];

   self.someCommonString = [self appendString:test1];
   self.someCommonString = [self appendString:test2];
   self.someCommonString = [self appendString:test3];

   NSLog(@"%@", someCommonString); 
}

- (void) dealloc
{
   [someCommonString release];
   [super release];
}
...

好的,在我分配myClass并执行doTheJob方法之后,我应该在someCommonString类proprety中使用@“one two three four”。我知道这是有效的,但也在泄漏。 test1,test2和test3是初始化NSString的3种方法,只有test2应该被释放,这是不言自明的,但更加担心将它们作为参数传递给appendString方法时会发生什么。因为我知道我有泄漏,但不知道如何处理1. stringToAdd参数[我应该在appendString方法中担心它吗?] 2.结果 - >如果我自动发布结果,我不知道结果将在何时被解除分配。 3. appendStringMethod中的sommeCommonString,我应该保留它,释放它还是不管它?

嗯:)

4 个答案:

答案 0 :(得分:1)

乍一看,在我看来,你似乎没有发布test2。将它附加到公共字符串后,您不再需要保留它。

self.someCommonString = [self appendString:test1];
self.someCommonString = [self appendString:test2];
self.someCommonString = [self appendString:test3];
[test2 release];

另外两个(test1test3)是自动释放的,所以你的线程会在某些时候回收它们。)

就您的appendString:方法而言,result 已经自动释放,事实上您可以将实施减少到

return [someCommonString stringByAppendingString: stringToAdd];

someCommonString完全不受操作的影响。 stringByAppendingString:会在selfstringToAdd的串联中返回新的自动释放字符串。

希望有所帮助

答案 1 :(得分:0)

  

...但我更担心将它们作为参数传递给appendString方法时会发生什么。因为我知道我有泄漏,但不知道如何处理   1. stringToAdd参数[我应该在appendString方法中担心它吗?] ...

-appendString:中没有泄漏。你正在通过stringToAdd而没有保留它,这没关系。 result已自动发布,您无需对其采取任何操作。

  

2。结果 - >如果我自动发布结果,我不知道结果将在何时被解除分配。

结果已经自动释放,并将在当前NSAutoreleasePool发布后立即发布。直到那时你可以传递它而不保留。

  

3。 appendStringMethod中的sommeCommonString,我应该保留它,释放它还是不管它?

不管它,它由访问者管理。但是,fedmest(你也是)说:释放test2

答案 2 :(得分:0)

你的代码中几乎没有问题,但基本问题是你需要NSMutableString字符串,而不是NSString才能使你的代码工作。

  1. 在init方法中,正确的代码是初始化,

    someCommonString = [[NSMutableString alloc] initWithString:@"one "];

  2. 你必须从init返回对象(self),否则它将不起作用,就像这样。

    return self;

  3. 如果你想追加字符串,它应该是NSMutableString,而不是NSString。

    [[self someCommonString] appendString:test1];

    [[self someCommonString] appendString:test2];

    [[self someCommonString] appendString:test3];

  4. 在dealloc方法中,你调用super的dealloc方法,而不是释放super。所以纠正它就像这样。

    [super dealloc];

  5. 无需发布test1test3,因为它们自动释放

  6. 我已经找到了正确的代码,试试这个。

    @interface myClass : NSObject {
    @private 
        NSMutableString* someCommonString;
    }
    @property (retain, nonatomic) NSMutableString* someCommonString;
    
    - (void) doTheJob;
    @end
    
    
    @implementation myClass
    @synthesize someCommonString;
    
    
    - (id) init 
    {
        self = [super init];
    
        if(self)
        {
            someCommonString = [[NSMutableString alloc] initWithString:@"one "];
        }
    
        return self;
    }
    
    - (NSString*) appendString:(NSString*) stringToAdd
    {
        NSString* result = [someCommonString stringByAppendingString: stringToAdd];
        return result;
    }
    
    - (void) doTheJob 
    {
        NSString* test1 = @"two ";
        NSString* test2 = [[NSString alloc] initWithString: @"three "];
        NSString* test3 = [NSString stringWithFormat:@"four "];
    
        [[self someCommonString] appendString:test1];
        [[self someCommonString] appendString:test2];
        [[self someCommonString] appendString:test3];
    
    
    
        NSLog(@"%@", someCommonString); 
    
        [test2 release];
    }
    
    - (void) dealloc
    {
        [someCommonString release];
        [super dealloc];
    }
    @end
    

答案 3 :(得分:0)

这是一种可以帮助您更好地处理@synthesize指令所发生的事情的技术。更改标题如下

@interface myClass : NSObject {
   @private 
   NSString* _bob;
}
@property (retain, nonatomic) NSString* someCommonString;

和您的班级文件

@synthesize someCommonString = _bob;  

如果重新编译代码,则会出现构建错误。修复这些问题,您将突然能够通过综合属性以及您正在访问的内容突然看到您正在访问的内容。

此外,如前所述,您需要在doTheJob方法中发布test2。