views:

56

answers:

3

Hi all,

I have an issue with releasing a view too many times. Although simple in theory because im moving uiview to uiview, which is a subclass of uiview and being animated and so on its not something that I can easily fix. It only crashes 10% and only under certain conditions and only 30% of the time even under these conditions.

So in other words its kinda complex. Sometimes in my dealloc method the retain count of this UIView is already 1 (which gets released when the view is released) and so shouldn't be released again. So what I did is this:

if ([mainView retainCount] > 1) {
    NSLog(@"released");
    [mainView release];
}

Consistant with the crashes released is usually called, but not always and it happens pretty much when I would sometimes expect it to crash. I've checked for leaks with this code and it never leaks.

Now the actual question... Is it wrong to release something due to its retain count? I've tried many different ways to fix this and so far this is the only reliable and non leaking one.

EDIT: If no then what is the better way to copy one UIView to another UIView?

mainView = newView;
[newView release];

I've tried releasing the mainView first then calling copy on the newView but this crashes. The above also works perfectly except the retain count is sometimes 1 lower than expected even though its never released ANYWHERE else in the code.

+5  A: 

Do not use the retainCount value.

Seriously, you should never use that value for anything really useful like this.

If you have memory leaks, or experience crash due to overreleases, fix them - they are bugs! And this is not the way to handle them.

Edit: Always a good read: Memory Management Guide

Eiko
updated question
Rudiger
You need to show more code, and tell us what you really want to do. Copying a view is somehow vague.
Eiko
There is not much more to it. There are two complex UIViews, if I need to create a new complex view I create a local UIView, create the contents of the UIView, animated between them get mainView = newView then release newView.
Rudiger
This is not copying anything - it just copies the reference. If you declare it with a copy-property, there is more going on, but then you need to use the dot syntax to invoke it.
Eiko
Well it works. As I said I tried to release the mainView (otherwise it would leak) copy the newView to the mainView and then release the newView. This crashes. But the above code works
Rudiger
It may seem to work, but probably different then you think. You are just reusing an old object, not copying. And if that dirty fix works, it's just pure luck to hide other bugs.
Eiko
Could you be a bit more helpful? I would like to do it the correct way but it crashes when trying to use copy.
Rudiger
I've tried removing the line seeing as you say it doesn't work anyway and the App no longer works correctly so its doing something.
Rudiger
Why downvoting? I cannot be any more helpful without seing much more code.
Eiko
It wasn't helpful, all you said was I was doing it wrong. UIView doesn't implement copy so I cannot copy one view to another.
Rudiger
How should anyone be able to solve your bugs without seeing your code? What do you expect? UIViews genearally are not meant to be copied, i.e. this is the first time I read that someone wanted to do this - while your code still didn't do it. If you want help with crashes, I'll gladly help. But I guess I don't want to any longer as you do a good job in not providing details, making it impossible.
Eiko
I know for a fact that the problem is with the above code and I stated above that I tried to use copy but it crashed. In your comments you said to use copy instead. UIView cannot use copy as it does not implement it. Hence the down vote as it is giving the wrong information.
Rudiger
It is not wrong. Your custom view could easily implement the copy interface (*you* were saying you'd copy it!). It seems you get several things wrong here - things nobody can know without seing your code (which you don't show). So you might reconsider your vote and - again - give more details next time!
Eiko
My question asks what is the better way to copy the UIView. You say it is easy but thats it, you haven't given a way to implement it. If I posted my code the method itself is 40 lines of code that calls other methods all up adding to about 200 lines of code. Its not something I can post here. All I have read is says UIView does not implement NSCopying and so should be done a different way.
Rudiger
There is rarely a reason to copy a UIView. Either reuse one you already had, or create a new one - the code should be there already. *copy* just doesn't make a lot of sense.
Eiko
Maybe you haven't had the need for it. Looking around the net I'm not the only one who has needed it. FYI the way others recommended and the way I have implemented is convert the UIView to an image, release the UIView, create it again with new values and then animate between them.
Rudiger
I give up. Copying and capturing are two different things with different use cases.
Eiko
A: 
mainView = newView;

it is not a copy but an assignment. The retainCount will be not increase. Then you don't have to make a release.

Benoît
Thats what I thought, and thats why I tried copy. But it crashes. Also doing it that way doesn't leak, works as expected and usually doesn't have a retain count problem.
Rudiger
You don't have to copy view !
Benoît
A: 

Do not use -retainCount.

The absolute retain count of an object is meaningless.

You should call release exactly same number of times that you caused the object to be retained. No less (unless you like leaks) and, certainly, no more (unless you like crashes).

See the Memory Management Guidelines for full details.


In this specific case, releaseing an object when you did not retain it is a recipe for disaster. If it doesn't crash now, it will someday, possibly due to a software update or seemingly unrelated change. It might only be working now because your memory management is wrong everywhere else.

As was stated, this:

mainView = newView;
[newView release];

Is not making a copy of the view. Worse, it is over-releasing the view (because nowhere do you retain it).

Using the copy method on views is not the right solution or, at least, would be exceedingly atypical. UI elements are not copied in that fashion.

Have you tried build and analyze and fixed any errors it indicates?

leaks may not show anything because there may still be a pointer to the leaked object floating about in reachable memory.

bbum