Objective C when to use alloc and when not to
Asked Answered
N

2

5

I'm trying to learn objective C and one of the things i find very weird to follow is when to use alloc and when not to. Take for instance this snip of code:

NSURL *url =[NSURL URLWithString:@"http://www.apple.com"];

Why don't you have to do something like this to alloc it first?

UIAlert *alert = [[UIAlertView alloc]]

I'm sure there is just some basic thing in objective C i'm missing, but oddly enough am having a hard time finding an explanation without posting. Thanks!!

Neck answered 6/11, 2011 at 14:1 Comment(2)
@jrturton: as I said, yes i have and it isn't making much sense to me, I usually get good explanations here, so I thought someone could give a good answer. Apple developer documentation is horrible and is known to be horrible. Please give actual answers to questions when responding to my stuff. i would appreciate it.Neck
Nowhere in your question do you say anything about having read the documentation or which parts you have problems with. Don't be so defensive!Posit
R
7

The problem with +alloc is that it retains its result, which is why it must be balanced with a call to -release or -autorelease later on. To avoid having to type that out over and over every time a class is used, API designers commonly create what's called a convenience constructor or convenience method. +URLWithString: is one of them, and internally it looks like this:

+ (id)URLWithString: (NSString *)str {
    return [[[self alloc] initWithString: str] autorelease];
}

So +alloc is getting called for you, and so is -autorelease.

Background

There are two broad kinds of methods in Objective-C: class methods and instance methods. Class methods are sent to a class itself and do not require the creation of an instance of that class. Instance methods are sent to an instance and can access the memory that instance occupies. Class methods start with +; instance methods with -.

+alloc is a class method. It's not a magical one with particular object-creating powers. All it does internally is something like:

+ (id)alloc {
    id result = malloc(class_getInstanceSize(self));
    if (result) {
        memset(result, 0, class_getInstanceSize(self));
        result->isa = self;
        result->retainCount = 1;
    }
    return result;
}

(It's actually a little more complicated than that but it should suffice here.) Note that +alloc is defined to be part of NSObject, not part of all objects. Cocoa memory management, with +alloc, -init, -retain, -release, etc. is not always part of Objective-C, and objects can be created that don't use it.

You can actually create instances of a class without calling +alloc if you know the right incantations. I wouldn't recommend it.

Raffin answered 6/11, 2011 at 14:12 Comment(1)
Thank you for the detailed answer. That sheds a little more light on what I was confused about. Thanks again!Neck
O
2

Use alloc method to create a new object, owned by you. I mean creating it like this

NSURL *url =[[NSURL allo]initWithString:@"http://www.apple.com"] , you become owner of this object. After you using it , lets say

NSLog ("Url path is %@",url);

You must release this object (url)

[url release];

This is one of main topic about memory managment in Objective C

What about your statment ,

NSURL *url =[NSURL URLWithString:@"http://www.apple.com"];

I must say that system will return a url with a string , but wich is not OWNED BY YOU , so you dont need to release it , because system automatically will release it (to this object automatically is send autorelease message)

Omora answered 6/11, 2011 at 14:12 Comment(2)
@devcode, ok that makes sense, but i guess then my next question would be, why ever care if you "Own it" Why not always not use alloc and then never worry about releasing it? What does this buy you?Neck
Because with object you own , you can control memory used by your app. You know that after you use this object , you should release it , by using convenient constructor (as you did) , system does not release that object immediatly , so your app still hold a block of unecessary memory . Using alloc is the best choise as a ruleOmora

© 2022 - 2024 — McMap. All rights reserved.