【问题标题】:NSMutableArray for Object which has NSString property causes memory leak具有 NSString 属性的对象的 NSMutableArray 会导致内存泄漏
【发布时间】:2010-04-22 09:42:18
【问题描述】:

我希望将对象添加到 NSMutableArray“myArray”,NSMutableArray 是 FileObj 的数组,它具有 NSString 属性“fileName”

#import <UIKit/UIKit.h>


@interface FileObj :  NSObject  {

    NSString *fileName;


}


-(void) setfileName:(NSString *)s ;
-(NSString *) getfileName ;


@end

//
//  File.m//

#import "File.h"


@implementation FileObj
 -(void) setfileName:(NSString *)s ;
{
    fileName=s;
}
-(NSString *) getfileName ;
{
    return fileName;
}
@end

我在这里初始化 myArray:

NSMutableArray *temarray;
temarray=[[NSMutableArray alloc] init];
self.myArray=temarray;
[temarray release];

将对象添加到 myArray 的代码

FileObj *newobj=[[FileObj alloc]init ];
NSString  *fieldValue2 = [[NSString alloc]   initWithUTF8String:@"aaaa"];
[newobj setfileName:fieldValue2];



[myArray addObject:newobj];

[fieldValue2 release]; //**if I enabled the line, it will cause crash**
                       //**if I disable the line, it will cause memory leak**


[newobj release];

欢迎评论

谢谢

交互开发

【问题讨论】:

  • 请试一试,NSString *fieldValue2 = [[[NSString alloc] initWithUTF8String:rowData] autorelease];

标签: iphone memory-management


【解决方案1】:

首先,您应该查看 ObjC 命名约定。 ObjC 中没有 -get 方法。使用您自己的 2 个字母(如 NS)为您的类添加前缀也是一个好主意。

您的 setter 值分配无效并且 NSString 初始化是不必要的。 我会强烈向您推荐介绍性材料!

@interface MYFileObject : NSObject {

    NSString *_fileName;
}

- (void)setFileName:(NSString *)theString;
- (NSString *)fileName;

@end

和实现

@implementation MYFileObject

- (void)setFileName:(NSString *)theString {
    [_fileName release];
    _fileName = [theString copy];
}

- (NSString *)fileName {
    return [[_fileName copy] autorelease];
}

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

@end

你会像这样添加一个对象...

NSMutableArray *myAry = [[NSMutableArray alloc] init];
MYFileObject *obj = [[MYFileObject alloc] init];
[obj setFileName:@"thefilename.txt"];

[myAry addObject:obj];
[obj release];

我建议使用属性而不是定义自己的 getter/setter。 你也可以使用 NSMutableArrays 的指定初始化器来快速创建数组。

查看如何使用属性:http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

【讨论】:

    【解决方案2】:

    为什么要使用 getter 和 setter?已经使用declared property了!

    @interface FileObj :  NSObject  {
        NSString *fileName;
    }
    @property(retain,nonatomic) NSString* fileName;  // <---
    @end
    
    ...
    
    @implementation FileObj
    @synthesize fileName;    /// <---
    -(void)dealloc {
      [fileName release];    // Remember to release the object on dealloc.
      [super dealloc];
    }
    @end
    
    ...
    
    FileObj *newobj=[[FileObj alloc] init];
    NSString  *fieldValue2 = [[NSString alloc] initWithUTF8String:@"aaaa"];
    
    newobj.fileName = fieldValue2;   /// <----
    
    [myArray addObject:newobj];
    
    [fieldValue2 release];
    [newobj release];
    

    【讨论】:

    • 这也适用于我。但是我选择了 eigner's 作为答案,因为我不需要更改更多的源代码。非常感谢。
    【解决方案3】:

    发生崩溃是因为不再保留 NSString 实例。

    一种常见的模式是保留 NSString 属性,可以使用 @property 声明式地保留,也可以手动保留。

    你应该像这样修改setter:

    -(void) setfileName:(NSString *)s ;
    {
        [s retain]; // <- Retain new value
        [filename release]; // <- Release old value
        fileName=s;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2011-04-18
      • 1970-01-01
      • 2017-03-18
      相关资源
      最近更新 更多