How to improve memory management when doing low level http work
I'm starting to cleanup an older prototype I worked on and it's doing a great deal of low level http work. The problem I'm having is how and when to do a release inside the "connectionDidFinishLoading" method below. I have some items only created inside the if but when I release them before the method call I get several BAD ACCESS errors and thought to ask how I should be doing memory management in this scenario.
- (void)searchForNewHats:(HatViewController *)hatVwController
{
responseData = [[NSMutableData data] retain]; //responseData is a property that I retain - fyi
hatController = hatVwController; //hatController is a property that I retain - fyi
NSURL *url = [NSURL URLWithString:@"http://localhost/jsondata"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:@"GET"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)conne开发者_开发问答ctionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *json = [responseString JSONValue];
if (json != NULL) {
NSArray *items = [json valueForKeyPath:@"d"];
HatParseJson* hatParseJson = [[HatParseJson alloc] init];
NSArray* hatz = [hatParseJson parseJson:items];
NSMutableArray* newHats = [[NSMutableArray alloc] init];
NSUInteger i, count = [hatz count];
for (i = 0; i < count; i++) {
Hat* obj = [hatz objectAtIndex:i];
[newHats addObject:obj];
//[obj release]; this blows up for example ...
}
[hatParseJson release];
[hatController newHatJsonFinished:newReleases];
}else {
[hatController newHatJsonFinished:nil];
}
[responseString release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
}
Thank you in advance
some updates and comments inline:
- (void)searchForNewHats:(HatViewController *)hatVwController
{
assert(0 == responseData);
responseData = [NSMutableData new];
assert(0 == hatController);
self.hatController = hatVwController;
NSURL * url = [NSURL URLWithString:@"http://localhost/jsondata"];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:@"GET"];
/* the delegate is retained in iOS, but not necessarily in OS X so... maybe you want to make connection an ivar of self? */
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
/* don't you want to hold on to this? */
[connection release], connection = 0;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)inConnection {
if (ConnectionIsAnIvar) {
if (self.connection != inConnection) {
assert(0 && "connection delegate messages sent to wrong instance. threading issue or worse?");
return;
}
}
else {
[connection release];
}
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *json = [responseString JSONValue];
if (json != NULL) {
NSArray *items = [json valueForKeyPath:@"d"];
HatParseJson* hatParseJson = [[HatParseJson alloc] init];
NSArray* hatz = [hatParseJson parseJson:items];
NSMutableArray* newHats = [[NSMutableArray alloc] init];
/* why not simply:
NSMutableArray* newHats = [hatz mutableCopy];
*/
NSUInteger i, count = [hatz count];
for (i = 0; i < count; i++) {
Hat* obj = [hatz objectAtIndex:i];
[newHats addObject:obj];
/* [obj release]; this blows up for example ... */
/* >> it should blow up. objectAtIndex: uses a get, not retain or copy */
}
[hatParseJson release];
[hatController newHatJsonFinished:newReleases];
}
else {
[hatController newHatJsonFinished:nil];
}
[responseString release];
}
[obj release]
is a wrong thing to do because you are just adding objects from one array to another. Instead you should release newHats
when done because you explicitly allocate it with alloc
.
精彩评论