what objects can be released immediately after adding to self.view - iphone

In a test program, I init 2 UITextFields, 2 UILabels, 1 UITextView and 1 UIButton programmatically in (void)loadview, and I try to release them immediately after [self.view addSubview:controlname] at the last of loadview. All of them work ok except UIButton. So when should I release button? And I wanna know what objects can be released immediately added to self.view?
Thanks a lot.

I'm assuming that you are creating the button with UIButton's +(id)buttonWithType: and if that is the case, you shouldn't release it.
I also would recommend using ARC so that you don't have to worry about this at all.

Well, to release or not to release depends on if you own the object or not, and this depends on how you are creating your objects, From the Memory Management Policy:
You own any object you create:
You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
Thus, if you created the object with some other method (one that doesn't start with these words) then you should not release it, since you don't own it.

Related

Cocos2d (ARC) not releasing memory of custom CCSprite class

I am using Cocos2d(ARC). i am making a game in which i am using custom CCSprite class
+(id)createMySprite
{
return [[self alloc] initMy] ;
}
This is my CCSprite Class . Where i allocate the memory. I can't write autorelease because of ARC. I have two CCLayer Classes. In first class has just play button with click of that button it replaces the screen and moves second screen. In 2nd Class I fetch to many Custom CCSprite Classes. When i replace to 1st CCLayer class, it never release the memory of 2nd class and memory will continuously increase. Then Crash after reach to 20-30 MB Live memory.
So I, need help regarding this.
Basically, headers are ARC compatible. Source code does not support ARC.
So, you compile Cocos2D as a static lib without enabling ARC and then you link to it in your code in which you can safely use ARC for your classes and custom subclasses of Cocos2D elements.
Please correct me if I am wrong, but there should be no problem with using ARC in your project and have say a CCSprite subclass which uses ARC and does not manually place retain and release messages. Right?
I know this has been around for quite sometime and most likely you have resolved it but for those whom are reading this and are still looking for an answer, here is my understanding of CCNodes and retain cycles.
Basically I have blog'ed about this and I have a design pattern that gets around over retained CCNodes. Here is the link. http://www.rotategears.com/development/ccnode-arc-memory-management/
In a nut shell, if you create a node ivar and don't specify the strength of the reference, it will get a strong reference. Then when you add it as a child to the node that will also maintain the reference, you would have created a double retain which causes problems when the OS tries to release it. The ivar must be week so that you only have a retain count of 1 in this container. Having said that, you then have to be carefull how you assign this weak reference to the ivar as it will need a reference count of 1 before you assign it or else the ivar will be set to nil.

iPhone Dev Objective-C - Object is being retained and I don't know where

I'm creating an iPad game that has a viewController that loads in its view from a nib file. The view has a bunch of buttons in it, which I linked up to UIButton * variables via interface builder (so each button is linked to a different variable). I checked the retain count right after they nib was loaded on one of the buttons (using my first button variable, b1) and it gives me a value of 2. Can anyone explain why it's 2? What are the two things that are retaining it right after the nib loads?
And now I'm even more confused because in my dealloc function, I released each of the button variables individually, and checked the retain count for one of them after and it's STILL 2! It should at least have gone down to 1, shouldn't it have? Should I release it several times in my dealloc function? If so, how many?
Thanks
Don't look at retain count.
Seriously.
Things other than you retain your stuff. Those numbers will move around underneath you for reasons that appear to make no sense, and then you'll come back here and post bewildered questions.
Just make sure your retains and releases balance. That's your only job.
If your IBOutlet properties are retained then you would have 1 retain there and another when the button gets added to the super view...
As Dan Ray says though, you shouldn't really worry about the retainCount...

Should I release an UIImageView added to my view if I will detect touch on it later on?

I've learnt that if you create an object, you own it and need to release it when you're done with it. In this case I create an UIImageView and add it to my view like this:
myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
[myImageView setFrame:CGRectMake(10,10,100,100)];
[self.view addSubview:myImageView];
[myImageView release];
If I later on want to detect touch on myImageView like this in my touchEnded-method:
if([touch view] == myImageView){
NSLog(#"TOUCHED!");
}
This works, but is this correct, since I now used myImageView after releasing it?
And how do I release myImageView from the self.view that I added it to earlier?
The cardinal rule of Cocoa memory management is that you should retain those things you care about, and release those things you do not care about. There are a very small number of exceptions to prevent retain loops (delegates and datasources are never retained), but this is the rule you should follow.
In this case, if you are storing the image in an ivar, I would continue to retain it, regardless of the fact that its superview will always retain it, and so you don't "have" to. But if the view is removed from its superview, you will wind up with a dangling pointer, and then you will crash, so I code defensively against that by retaining. If you used an accessor here (which you should), then this would be automatic and much safer.
Apple has grown more consistent about this in iOS, switching their recommendation about IBOutlets. On Mac, you do not retain your IBOutlets, but in iOS, Apple explicitly instructs you to do so. This is similar to the situation you are discussing, and I agree with Apple's move towards a safer approach.
As long as your myUIImageView object has a retain count > 0, it will still exist and you can continue using it. When you first add it as a subview, it gets a retain message so it's retain count is likely 2. Then you send it release, so its retain count is reduced to 1. This means it still exists in memory. Now, if you sent it release again, or sent it removeFromSuperView then its retain count would be zero, and you'd lose it.
The behavior is erratic, sometimes you may see it works, sometimes you get a crash.
If you want to use that variable to point to your image view, retain the ivar (by using a retain property). This way you ensure that the image view is available for your controller class to use.
Assuming myUIImageView is an ivar of your custom UIView subclass, your code will work as long as your image view stays in his superview. The image view instance may be deallocated and you may end with an invalid pointer referencing a deallocated object. At best you crash.
According to memory management guidelines, you should consider your image view <-> custom uiview subclass relation as wether:
strong reference. You own the image view (as you created it), and are responsible for retaining / releasing it
weak reference. You don't own the object, thus keeping a reference to it may be dangerous.
in your case, it's probably a strong reference. your myUIImageView ivar should be a nonatomic retained property of your object.
If you need to access your UIImage at some point in the future, you need to retain it.
How you do this is at your discretion, but you should not rely on the UIView to retrain your objects for you. The situation you've created works for now, but it's fragile.

Does this have to be released?

I've done a lot of research on when it's correct to release things, but it's all confusing to me. I think sometimes the Leaks program is off. Anyway...
background is a UIImageView
background.image = [UIImage imageNamed:#"greenbackground.png"];
Do I have to release background? I never alloced it and it's not set as a property, so I'm thinking no.
Actually, you do need to release it.
UIKit uses Key Value Coding to assign IBOutlets to a controller. By default this is causing your controller to increase the retain count by one. From the KeyValueCoding docs:
If you have not defined a setter, then UIKit will directly set the value of the instance variable and then, for anything other than an NSNumber or NSValue date type, UIKit will retain the value after autoreleasing the instance variable’s old value.
Unless you explicitly set a #property with assign, you need to release the object.
No you don't. That factory method returns an autoreleased UIImage. A good rule of thumb that helps me in objective c is whenever you see alloc, copy or new in a method name... you are incharge of releasing the returned object... everything else should be an autoreleased object. Also, I can't think of any class level methods (+) in the api that don't return autoreleased objects.
EDIT
I read your question too quickly... Mark is correct on this. If you are ever in doubt about these kinds of things you can always do a simple test and log the retain count.
Mark's right that you are responsible for releasing your UIImageView if it is instantiated from a nib, if background is an IBOutlet, and if background does not have a corresponding "assign" property.
Even if you're managing that correctly, you may still see some extra memory in use in ObjectAlloc after you release your UIImageView. That's because -[UIImage imageNamed:] caches the image you load in anticipation of you calling -[UIImage imageNamed:] again later. The image is not necessarily uncached even when the returned UIImage gets deallocated.

iPhone Development - Release an autoreleased object

What happens if I release an autoreleased object? Its an autoreleased UIButton I want to release and the only way to create a UIButton is to use the convinience method buttonWithType:. Will it be released from memory like a normal object? Or should I just let the autoreleasepool take care of it? I wouldn't have made it autoreleased in the first place if I could.
Thanks!!
You should just let the autorelease pool take care of it. Once you add your button to a parent view, that view will retain it, and the autoreleased handle will get taken care of by the autorelease pool.
The easiest way to think of it is in terms of ownership—you don't "own" the reference you got via a convenience method, so you don't need to bother releasing it unless you retain it as well.
You must only release an object which you own. +buttonWithType: does not return an owned object, so you must not release it.
Review the Cocoa Object Ownership Rules.
Why are you trying to avoid an autoreleased object here? Presumably you are creating the button because you are using the button and inserting it into a view hierarchy, so there is no real reason to accelerate the draining of the autorelease pool which contains the button.