Can I early-release an autorelease object? - objective-c

i.e. would cause the object to be released immediately and not have to be released by the pool if I did this?
[[NSArray arrayWithCapacity:100] release];
Can't find a clear explanation in the docs about this.

It would likely crash when the object would normally be autoreleased. autorelease means "delayed release", so it will be released: just later. Since the object won't exist later as you are manually releasing it, you will likely crash due to the runtime sending the -release message to your now-deallocated object.
Edit: Note that if you -retain objects that come autoreleased, you do have to -release them: you are taking ownership.

I realise that this is stupid now, and that I shouldn't be releasing something I don't own.

If you don't want the object to go into the auto-release pool, you can do a manual alloc and initWithCapabity. If you do that, you'll have to manually release it at some point.

Related

What happens if your mark an autorelease object as autorelease

My question may sound stupid an all, but I like to know what happens if I mark an autoreleased object as autorelease. Will it be released twice? Or nothing happens? For example:
Obj * obj = [[Obj create] autorelease];
Let's say [Obj create] returns an autoreleased object.
If I add another autorelease, what happens then?
Yes, sending autorelease twice will release the object twice. If your create method returns an autoreleased object and you send another autorelease message to it, your app will crash, because you'll be releasing a deallocated object.
Having said that, why don't you use the new Automatic Reference Counting (ARC)? You don't have to worry about (auto)releasing objects anymore.
You use the Class Method(+), you should not to care the memory. People use Class Method one reason is that it can return an autorelease object. If you release or autorelease the object which the Class Method returns, it will crash.

what if we retain or autorelease pool? why?

Language : Objective C
Questions:
why we should always use 'drain' over 'release' for an autorelease pool ?
what will happen if [pool retain]; ? why ?
what will happen if [pool autorelease]; ? why ?
The documentation doesn't give a direct answer to this. However, there is a very clear answer; because it doesn't make sense.
P.S: drain and release are the exact same thing on an autorelease pool.
Under garbage collection, release acts as a no-op, whereas drain triggers garbage collection, and then release (which is unusual), so drain should be the preferred way of emptying a pool. retain and autorelease are intentionally disabled, as per the documentation.
WWDC 2011 Session 323, Introducing Automatic Reference Counting, explains that autorelease pools are not real objects, so they cannot be retained. Retaining an autorelease pool will cause an exception. Watch the video at 24:27 or read slide 23 of the Keynote. You must be a registered developer to access.
Under ARC, autorelease syntax is a scoped block of code preceded by #autorelease. According to Apple, this syntax more accurately describes what autorelease does under the hood.

Objective C - Memory Management and autorelease ???

Does autorelease guaranty that at the end of blocks the object will get released?
Or is it better to manually release objects?
It guarantees it will be released sometime after the block executes, not necessarily immediately after. It's up to the runtime to determine exactly when.
It's not big deal unless you're doing something with a lot of autoreleased variables, like creating them in a big loop, or if you're creating large autoreleased objects, like UIImages. In these cases, you should manually release when you're through, otherwise autorelease is perfectly acceptable.
If an object is autoreleased, you MUST not manually release it (unless it is retained of course). The NSAutoRelease pool which is part of the UIKit event handler will release it for you. If you were to manually release the object, the pool may cause a crash or other undefined behavior as the object will be doubly-released.
If there are cases where you generate a lot of objects or use a lot of memory in objects, you can pre-emptively autorelease them (perhaps in your loop) by creating your own NSAutoReleasePool - pools can be nested.
It's better to release objects rather than autorelease, unless of course you have an explicit reason to use autorelease, for example use autorelease when returning an object the method retained and you can't avoid it.
Basically autorelease should be used as an excuse to completely avoid memory management. You want to release objects as soon as you possible can. Autorelease just says the object will be released some time in the future.

Changing auto-released object to non-auto

Is there a way to change an autoreleased object to one that is non-autoreleased?
NSCoder's decodeObjectForKey returns an autoreleased object, which messes with a couple memory systems in my app. How can I change its returned value to a non-autoreleased object?
I know I can run retain on it, but if I release it, it'll still remain autoreleased. Whereas, I want to manage the memory myself.
Set up an autorelease pool before you retrieve the autoreleased object. It will be in that autorelease pool. Retain the object. Now release the autorelease pool. Your object is no longer in an autorelease pool. It's retained, and it's now your responsibility to release it.

What is the difference between releasing and autoreleasing?

I still have some unclear understand about release and autorelease. What are the difference between both of them? I have this code. For facebook connection. I crash it sometimes when I go to Facebook login, I doubting maybe it is because I don't release the object nicely.? Thanks for any helps
if (_session.isConnected) {
[_session logout];
} else {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[dialog show];
}
The Memory Management Programming Guide for Cocoa will soon be your best friend. In brief, object instances in Cocoa are memory managed using reference counting (unless, of course you're using garbage collection on OS X). An object indicates that it wants to 'retain' an ownership interest in an other instance--keep it from being deallocated--by sending it a -retain message. An object indicates that it wants to release that interest by sending the other instance a -release message. If the number of objects that have 'retained' and ownership interest in an object drops to 0 (i.e. when the last of the owning instances sends a -release message), the instance with a 0 retain count is deallocated.
It's sometimes convenient to say "I want this instance to be released some time in the future". That's the purpose of -autorelease. Sending an -autorelease message adds the receiver to the current NSAutoreleasePool. When that pool is drained, it sends a -release message to all the instances in the pool. An NSAutoreleasePool is automatically created at the start of each iteration of each thread's run loop and drained at the end of that iteration. Thus, you can do something like this in a method:
- (id)myMethod {
return [[[MyObject alloc] init] autorelease];
}
The caller of this method will get back an instance that they can -retain if they wish to keep it. If they don't retain it, it will stick around at least until the enclosing autorelease pool is drained:
- (void)someOtherMethod {
...
id instance = [obj myMethod];
... // do more with instance, knowing that it won't be dealloc'd until after someOtherMethod returns
}
Releasing means you release that right away.
Autoreleasing means you want the variable to be released on the next autorelease pool.
You use autorelease when you want to keep retaining the variable but don't want to create a memory leak. You use release when you don't need the variable anymore.
Sample:
- (NSNumber *)return5 {
NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
[result autorelease];
return result;
}
Why do we use autorelease there?
If we use [result release] instead, variable result will be destroyed AT that time. Which means that the returned value will be garbage.
If we do not release at all, variable result will be hold FOREVER incurring memory leak.
We can tell every caller to the function to release result but that would be a headache and prone to error.
So we use autorelease. We mark the variable to be released on the next autorelease pool. Basically we mark the variable to be released near the alloc. Hence the mantra alloc is paired with release in the same function holds all the time.
Actually, you'll do fine changing all release into autorelease. Your memory use won't be efficient, however, the effect is minimal. All variables, in all programming language is effectively autoreleased.
Anyway, use ARC.
background discussion:
objective-c is reference counted, so objects are deleted when the reference count reaches 0. release reduces the reference-count immediately, autorelease reduces it when the autorelease-pool is popped
when to use:
use autorelease when allocating the object if
you do not need it after the current function
it will be retiained by some other objet/function and will be released by a later by the retaining code
when the logic of the current function is tricky, so you would have to send release in a dozen different places before doing a return
use "manual" release
to revert a previous retain (in case you are implementing a library)
if you need precise control of freeing objects (e.g. they use lots of memory or the autorelease pool will not be popped for some time)
but really my freand:
read the Memory Management Programming Guide for Cocoa as suggested by Barry and run your code with instruments (zombies and leaks) often to catch any and almost all memory management errors.
Erik
According to the Memory Management Programming Guide for Cocoa:
The autorelease method, defined by
NSObject, marks the receiver for later
release. By autoreleasing an
object—that is, by sending it an
autorelease message—you declare that
you don't want to own the object
beyond the scope in which you sent
autorelease.
Also:
The autorelease method thus allows
every object to use other objects
without worrying about disposing of
them.