NSString 内存泄漏

发布于 2024-11-30 17:09:03 字数 3055 浏览 0 评论 0原文

我在寻找 Objective C 中的内存泄漏以及如何修复它们方面有点新。我知道如何使用 alloc/init/copy 和 release/retain 但是(至少我这么认为:-))但是我的 IOS 应用程序中有一些奇怪的内存泄漏。

-(void) sendStats {

// read the app settings
plistHandler *readData  = [[plistHandler alloc] init];
[readData setPlistName:@"Settings"];
NSDictionary *settingsArray  = [readData readPlist];
[readData release];

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:[NSString stringWithFormat:@"%@", [settingsArray objectForKey:@"range"]]];
[f release];

int rangeForUrl;

if(myNumber != nil) {
    rangeForUrl = [myNumber intValue];
} else {
    rangeForUrl = 10;
}

// get uniqe device ID
UIDevice *getdev = [UIDevice currentDevice];
NSString *uniqueIdentifier = [getdev uniqueIdentifier];

NSString *deviceId  = [NSString stringWithFormat:@"IOS-%@", uniqueIdentifier];

// get the unix timestamp
NSDate * past = [NSDate date];
NSTimeInterval oldTime = [past timeIntervalSince1970]; 
NSString * unixTime = [[[NSString alloc] initWithFormat:@"%0.0f", oldTime] autorelease];


// send the data with a post request to the API
HttpRequest *data = [[HttpRequest alloc] init];
data.postData   = [NSString stringWithFormat:@"&device=%@&age=%@&gender=%@&latitude=%@&longitude=%@&timestamp=%@", deviceId, [settingsArray objectForKey:@"age"], [settingsArray objectForKey:@"gender"], @"00", @"00", unixTime];

data.controller = @"sendDevice";

NSString *url   = [NSString stringWithFormat:@"http://www..eu/api/send_device"];

[data loadHostName:url];

[data release];

//NSLog(@"string s: %@", data.postData);

}

根据 Xcode Instruments => 这是内存泄漏leaks:

泄漏对象 # 地址大小 负责库 负责框架 NSCFString, 0x16cb40 144 Bytes Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]

这是我的代码中带有“data.postData = ...”的行。有人可以帮我吗?

这就是我在 httpRequest: 类中使用 postData 的方式,

- (void)loadHostName:(NSString *)hostName {



responseData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", hostName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

if(authString) {
    [request setValue:authString forHTTPHeaderField:@"Authorization"];
}

if([postData isKindOfClass:[NSString class]] && postData != @"") {

    NSData *dataToPost = [postData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d",[dataToPost length]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Current-Type"];
    [request setHTTPBody:dataToPost];

}

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];

}

当然还有:

NSString *postData; @property(非原子,保留)NSString *postData;

@synthesize postData;

I'm kinda new in finding memory leaks in objective c and how to fix them. I'm know how to use alloc/init/copy and release/retain but ( a least i think so :-) ) but i have some strange memory leaks in my IOS app.

-(void) sendStats {

// read the app settings
plistHandler *readData  = [[plistHandler alloc] init];
[readData setPlistName:@"Settings"];
NSDictionary *settingsArray  = [readData readPlist];
[readData release];

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:[NSString stringWithFormat:@"%@", [settingsArray objectForKey:@"range"]]];
[f release];

int rangeForUrl;

if(myNumber != nil) {
    rangeForUrl = [myNumber intValue];
} else {
    rangeForUrl = 10;
}

// get uniqe device ID
UIDevice *getdev = [UIDevice currentDevice];
NSString *uniqueIdentifier = [getdev uniqueIdentifier];

NSString *deviceId  = [NSString stringWithFormat:@"IOS-%@", uniqueIdentifier];

// get the unix timestamp
NSDate * past = [NSDate date];
NSTimeInterval oldTime = [past timeIntervalSince1970]; 
NSString * unixTime = [[[NSString alloc] initWithFormat:@"%0.0f", oldTime] autorelease];


// send the data with a post request to the API
HttpRequest *data = [[HttpRequest alloc] init];
data.postData   = [NSString stringWithFormat:@"&device=%@&age=%@&gender=%@&latitude=%@&longitude=%@×tamp=%@", deviceId, [settingsArray objectForKey:@"age"], [settingsArray objectForKey:@"gender"], @"00", @"00", unixTime];

data.controller = @"sendDevice";

NSString *url   = [NSString stringWithFormat:@"http://www..eu/api/send_device"];

[data loadHostName:url];

[data release];

//NSLog(@"string s: %@", data.postData);

}

This is the memory leak according to Xcode instruments => leaks:

Leaked Object # Address Size Responsible Library Responsible Frame
NSCFString, 0x16cb40 144 Bytes Foundation -[NSPlaceholderString initWithFormat:locale:arguments:]

This is the line with "data.postData = ..." in my code. Can someone help me out?

this is how I use postData in the class httpRequest:

- (void)loadHostName:(NSString *)hostName {



responseData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", hostName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

if(authString) {
    [request setValue:authString forHTTPHeaderField:@"Authorization"];
}

if([postData isKindOfClass:[NSString class]] && postData != @"") {

    NSData *dataToPost = [postData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d",[dataToPost length]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Current-Type"];
    [request setHTTPBody:dataToPost];

}

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];

}

with of course:

NSString *postData;
@property (nonatomic, retain) NSString *postData;

and

@synthesize postData;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自此以后,行同陌路 2024-12-07 17:09:03

您需要在dealloc中释放postData

看起来现在已经修复了。但我真的不明白 dealloc 是如何工作的。我从来没有做过
在 postData 上分配/初始化。这是否意味着我的 .h 文件中的每个对象都像
postData需要在.m文件中的dealloc中释放吗?

说到属性,您需要在 dealloc 中释放所有标记为分配的属性(以及您拥有的任何非属性实例变量)。非分配属性拥有由支持实例变量持有的对象,因此您需要通过在dealloc中向其发送release消息来放弃它的所有权。

来自 “Objective-C 编程语言”

声明的属性与 @synthesize 指令一起采用
访问器方法声明的位置;当你合成一个属性时,
编译器根据需要创建访问器方法。然而,没有
属性声明和 dealloc 之间的直接交互
方法—属性不会自动为您释放。宣布
然而,属性确实提供了一种有用的方法来交叉检查
dealloc 方法的实现:您可以查找所有
头文件中的属性声明并确保该对象
未标记分配的属性将被释放,而标记为分配的属性将被释放
未发布。

我还建议您阅读 “内存管理编程指南”

You need to release postData in dealloc.

looks like its fixed now. But i dont really understand how the dealloc works. I never did a
alloc/init on postData. Does this mean every object in my .h file like
postData need to be released in the dealloc in the .m file?

Speaking of properties, you need to release in dealloc all your properties not marked assign (along with any non-property instance variable you own). Non-assign properties own the object held by the backing instance variable so you need to relinquish ownership of it by sending it a release message in dealloc.

From "The Objective-C Programming Language":

Declared properties, along with the @synthesize directive, take the
place of accessor method declarations; when you synthesize a property,
the compiler creates accessor methods as needed. However, there is no
direct interaction between property declaration and the dealloc
method—properties are not automatically released for you. Declared
properties do, however, provide a useful way to cross-check the
implementation of your dealloc method: you can look for all the
property declarations in your header file and make sure that object
properties not marked assign are released, and those marked assign are
not released.

I would also recommend you to read the "Memory Management Programming Guide".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文