memory access error when releasing a newly created object
I'm having an issue understanding why releasing an object that I just created is causing a memory access error in my application.
I'm creating a bunch of objects and adding them to an NSMutableArray. After I add them to the array, I release them. The first time the function runs, things go smoothly. The second time the function runs, releasing the object crashes the application and I'm not sure why.
Here is the part of the function in question (full project source is available here: http://github.com/cpjolicoeur/echowaves-notifier-osx)
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:echowaves.responseData encoding:NSUTF8StringEncoding];
[echowaves.responseData release];
...more code...
[[echowaves updatedConvos] removeAllObjects];
NSDictionary *dictionary = [responseString JSONValue];
if ( [dictionary count] ) {
for (NSDictionary *subscription in dictionary ) {
UpdatedConvo *convo = [[UpdatedConvo alloc] initWithConvoName:[[subscription objectForKey:@"subscription"] objectForKey:@"convo_name"]
convoURI:[[subscription objectForKey:@"subscription"] objectForKey:@"conversation_id"]
unreadCount:[[[subscription objectForKey:@"subscription"] objectForKey:@"new_messages_count"] integerValue]];
[[echowaves updatedConvos] addObject:convo];
[convo release]; // THIS LINE CAUSES CRASH 2ND TIME THROUGH
}
} else {
...more code....
}
}
The app crashes on the [convo release]
line the 2nd time through the function. Since the convo object is created two lines before it I'm not sure why.
I'm under the impression that the UpdatedConvo *convo = [[UpdatedConvo alloc] initWithConvoName...]
call will create the object and give it a retain count of 1. Then when I add the object to the [echowaves updatedConvos]
NSMutableArray object, it should bump the retain count by 1 (now count is 2). I'm done with that "temporary" convo object so I then release it, which should move its retain count back down to 1, correct??
What am I missing here?
To开发者_如何转开发 get the app to run successfully, I have to comment out the [convo release] line. I don't know why though, and I feel that this is probably giving me a slow memory leak since that newly created UpdatedConvo object isn't being freed from memory properly.
Your method should work. It is a common pattern to create an object, add it to a dictionary, and then release it.
The fact that it doesn't work suggests that the problem is elsewhere. The first place to check is in the UpdatedConvo
class itself. Does it do anything fancy in its dealloc
method?
edit: The problem is definitely in UpdatedConvo
. You assign your instance variables (with =
) in your init
method:
- (id)initWithConvoName:(NSString *)convoName
convoURI:(NSString *)convoURI
unreadCount:(int)updatesCount
{
if ( self = [super init] ) {
ewURI = convoURI;
ewName = convoName;
newMessagesCount = updatesCount;
}
return self;
}
But then you call release
on them in dealloc
:
- (void)dealloc {
[ewURI release];
[ewName release];
[super dealloc];
}
Using =
in the init method does not increase the retain count, so when you release them, you are actually reducing the retain count too far.
As e.James already mentioned: UpdatedConvo seems to be your problem.
I looked at the github project you posted.
Probably you are over-releasing in UpdatedConvo:
- (void)dealloc
{
[ewURI release];
[ewName release];
[super dealloc];
}
You are neither creating, nor retaining ewURI and ewName in the class.
So you shouldn't release it there.
Update: Fixed a misleading typo (I wrote "releasing" instead of "retaining" in last sentence)
Update2:
I would run your code through Instruments.app with the "Zombie" and "Leaks" presets.
If you haven't tried Instruments before, this is a great opportunity to see it at work.
精彩评论