请帮助;
标头文件
#import <Foundation/Foundation.h>
@interface MyClass : NSObject {
NSMutableString * myString;
}
@property (nonatomic, retain) NSMutableString * myString;
-(id) init;
-(void) dealloc;
@end
实施档案
#import "MyClass.h"
@implementation MyClass
@synthesize myString;
-(id) init {
if ((self = [super init])) {
self.myString = [[NSMutableString alloc] init];
}
return self;
}
-(void) dealloc {
[super dealloc];
[self.myString release];
}
@end
用法
MyClass * m = [[MyClass alloc] init];
[m release];
//-- Xcode 4 profiler reports a memory leak here.
但是,当类的实现文件中的代码更改为不使用[self.myString .....]表示法时,则不会报告内存泄漏。
所以,
-(id) init {
if ((self = [super init])) {
myString = [[NSMutableString alloc] init];
}
return self;
}
}
和
-(void) dealloc {
[super dealloc];
[myString release];
}
工作正常。没有报告内存泄漏。
任何想法 - 它是剖析器还是我(好看)?
答案 0 :(得分:2)
使用您的setter,造成内存泄漏 。您的内存泄漏是由于您没有正确管理内存造成的!
如果您声明以下属性
@property (nonatomic, retain) id value;
这意味着编译器生成的方法看起来像这样(高度简化):
- (id)value {
return value;
}
- (void)setValue:(id)aValue {
[value autorelease];
value = [aValue retain];
}
使用点符号时,self.value = obj
会被[self setValue:obj]
删除。因此,您实际上导致obj
保留在设置器中。如果您最初创建对obj
的拥有引用(使用+alloc
而没有相应的-release
或-autorelease
),则会过度保留obj
,它永远不会被解除分配。因此,你需要做这样的事情:
id obj = [[[NSObject alloc] init] autorelease];
self.value = obj;
或
id obj = [[NSObject alloc] init];
self.value = [obj autorelease];
或
id obj = [[NSObject alloc] init];
self.value = obj;
[obj release];
无论你做什么,你都需要确保当你断言对象的所有权时(保留它),你也要释放它。
答案 1 :(得分:0)
Objective-C中的Setter方法等同于重新获得新对象和释放旧对象。在您的情况下,编译器将为myString属性生成一个类似于...的
的setter方法- (void)setMyString:(NSMutableString*)aString {
[myString autorelease];
myString = [aString retain];
}
当你在init方法中调用self.myString =时,这会转换为对setter的调用。然后,setter会保留您传递给它的对象。因为你直接分配了NSString,它的保留计数为1,然后调用setter,保留计数变为2。
有两种解决问题的方法,第一种方法是在分配之后添加对[myString autorelease]的调用。或者其次切换你的init方法直接分配ivar ......
// in your init method...
myString = [[NSMutableString alloc] init];
避免在init方法中使用setter是个好主意,不是因为保留计数,而是因为整个对象尚未完全初始化。
答案 2 :(得分:-3)
@property(非原子,RETAIN)
你保留了我的朋友。您必须释放该对象两次,因为保留计数为2这是你应该在INIT方法中做的事情:
NSString *str = [[NSString alloc] initWithString:@"Hello World!"];
self.myString = str;
[str release]; // dont leak
另外,我不建议在类本身中使用self.someProperty。这样做需要额外执行一次objc_msgSend()才能访问您的变量,并且会降低您的应用程序速度。