The rules for memory management are generally quite simple. Most problems come from overthinking them and trying to guess what other parts of the system are going to do, rather than just following the rules as written.
The first rule of Memory Management:
If you cannot follow rule one (for instance, you are developing for OS X 10.5 as I do), then here are the rules:
- You must balance each call you make to
+alloc…
,+new…
,-…copy…
or-retain
with a call to-release
or-autorelease
.
That's really it. Everything else is really just commentary to help you follow that rule. So, you called [NSAlert alloc]
and [NSTextField alloc]
, you need to call release
on those objects.
Why doesn't it crash?
Because a leak is not going to crash unless it causes you to run out of memory.
Why doesn't it leak?
The most likely cause is that you're only running it once and then expecting Instruments to detect the leak. It may not show up if you only run it once. It depends on how NSAlert
is internally implemented. Instruments finds leaks by walking all the pointers in the system and determining if any accessible pointers still reference a piece of allocated memory. There are many cases when a "leak is not a leak."
But this also suggests you're not running the static analyzer, because the analyzer should definitely have detected that leak. Run the static analyzer (Cmd-Shift-B) all the time and clean up what it finds.
the accessory view shouldn't be release.
That's not what the link you reference says. You shouldn't add an extra release
. But in the referenced code, you'll notice that they release the view to balance their own +alloc
.
… retainCount …
Never use -retainCount
. Not even for debugging. Not even for anything else. There is no point at which retainCount
is going to return you a piece of information that is going to be more enlightening than confusing. Why is it greater than you think it should be? Because other objects are retaining the alert view? Which objects? That's not your business. That's an internal implementation detail, subject to change. It could be pending autorelease
calls, which show up temporarily as a "too high retainCount
". It could be the run loop. It could be an internal controller. It could be anything. Calling retainCount
tells you nothing useful.
Now that you understand manual memory management, switch to ARC and think about object graphs rather than retain counts. It is a much better way to deal with memory.