I am new to cocoa-touch, and really unmanaged languages all together. While I have a firm grasp of the syntax, I am questioning whether I am releasing an object correctly.
I have a view that creates an object,
Communication *comm = [[Communication alloc] init];
[comm doSomething];
[comm release];
I understand that I have to destroy this object because I am allocating it and it will not auto release.
I call a method on the object that goes out to my server and grabs information. When the data returns it throws an event which my "message dispatcher" responds to. I do not want to destroy the object until it returns back from the server -- and this is where my confusion is at.
If I release this object directly after I make the call, will it destroy the object? (Which I don't want to do.)
How do I properly destroy this object after it throws the event with the data I am waiting for? This would occur within a DataFinishedLoading event on my comm object. Should it destroy itself, and is this the right way to do it?
The view calling my object essentially says, create this object, call this method, and go about your merry way. It doesn't care about what happens after it calls the method -- whether it brings back information or not. It simply listens on a method for any data that may come across at a later time. I have no reason to hang onto a reference of the object, as I will never use the same instance after I make the call -- that is besides cleaning up after myself.
A release only destroys the object if the last retainer released it.
For example, say you allocate your Communication object. It is implicitly retained once. Then you retain it five times. You need to release/autorelease the object six times until it gets destroyed (its dealloc method is called).
There is an internal counter, the retainCount. When you create an object, it is set to 1. Now every retain increases the counter, and every release decreases it. autorelease also decreases the counter, but not immediately. Once the counter drops to 0 Objective-C knows that the object is no longer needed and destroys it (by calling the object's dealloc). Warning: do not rely on the retainCount, do not even look at it. You should only care that your alloc/copy/new/retain calls are balanced with a corresponding release/autorelease later on.
In your above example, comm will likely be destroyed when you call release. It depends on something else retains it during doSomething.
If you want to hold onto an object while it does something asynchronously, put it in a retained property. When it informs you that it is done, set the property to nil which will release it.
Related
I have created an object using alloc/init method, and after I release it -dealloc should be called immediately as per documentation. I set a breakpoint on -dealloc method but it isn't hit, and my -dealloc method is not called.
Please tell me what is the reason behind that, and what is use of dealloc method in objective c ?
The -dealloc method is not always called when you expect it to be called. The runtime might also have issued a -retain on your object for internal reasons.
It's also possible that you have (directly or indirectly) caused an extra -retain to be issued. If the retains/allocs and releases are not balanced, you'll never see -dealloc called. It helps to turn on the Static Analyzer, to make sure your calls balance.
Just follow the memory management rules, don't second guess the runtime, and let the memory management system do its job.
The answers to When does dealloc method call? may help you understand what you're seeing.
because it still has reference. that means its reference count not reached to zero. i don't know your code, where it is referencing. but it is not calling that means somehow still it has reference. it may be because of strong relationship or parent-child relationship
all Objective-C objects are allocated on the heap, so they must
therefore be deallocated somewhere if you are not to run out of
resources.
This gave way to the reference counting method, which is still used
today: each object keeps count of any references held to it. If you
receive an object and you want to keep it, you retain that object,
incrementing its reference count. When you are done with it, you
release it, which decrements its reference count. Once that count
reaches zero, it is inferred that no one is referencing the object and
it is automatically deallocated using the -dealloc method.
Additionally, an object could be told to “release at some point in the
(hopefully) near future” using autorelease pools. The idea is that
somewhere on the stack (typically at the start of a thread or while
responding to input events) an autorelease pool is created and pushed
onto a stack. Any object can then be sent an -autorelease message, and
it is assigned to that pool.
When the pool object is deallocated, it simply sends a -release
message to all its assigned objects. That way, any objects that are no
longer used (i.e. they haven’t been explicitly retained) are then
deallocated.
The dealloc is called (at more cases) whenever your object is released. You can't directly call this method.
#interface myViewController:UIViewController
{
NSString *myStr;
}
#end
Here the dealloc method in the #implementation of myViewController will be called (at most cases) when the myViewController object is released, not when myStr is released.
Although you don't have to use if you ARC.
I want to destroy class instance by its own method. For example:
obj = Object()
obj:destroy()
type(obj) == nil
Object is implemented on C. Is it possible?
If it's not possible, Second way is:
_G["obj"] = nil
collectgarbage()
Thanks!
I want to destroy class instance by its own method.
You should avoid this at all costs. Only expose an explicit destructor routine in Lua if you absolutely need to.
The correct way to handle this is to give your Lua C object a metatable with an __gc metamethod. This metamethod will be called right before Lua garbage collects the object.
If you absolutely must use an explicit destructor function (because you want the user to be able to release expensive resources immediately when they're done, without waiting for garbage collection), then you need to do two things:
Do not require the user to explicitly destroy the object. That is, the object should be able to be destroyed either via destructor or via garbage collection.
Do not break the object when it is explicitly destroyed. Every function that takes this object (member functions or free functions) needs to still work if the user called the explicit destruction function. Those functions may do nothing, which is fine. But the program shouldn't crash.
Basically, your object needs to still be in an "alive" state when it was explicitly destroyed. You need to have the object be a zombie: alive, but not very useful. That way, your program will still function even if it doesn't do the right thing.
Simple obj = nil in your example is enough. Note that you do not destroy content of object, you delete a reference that was in the variable obj, making real object somewhere in memory have one less reference and, if it reached 0 references, unreferenced an eligible for GC.
If your object doesn't have some external task to perform on destruction, that's pretty much all you need. Just lose all references by letting them go out of scope or overwriting variables/table members that contain those references with something else or nil. Otherwise you'd need to call object-specific destructor first and only then remove references.
It is not possible to make such a destructor automatically remove all references from everywhere, but at least it can clear object's internal state and set some internal flag that object is no longer usable or ready to be re-initialized.
It is possible, to some degree. You can create a subtable within the object as a private data store. That subtable is managed solely by the object and therefore can only have one reference. If you define a destructor method for the object, then it would delete the respective subtable, making it eligible for garbage collection. Of course, the parent table would still exist, leaving only the methods which do not occupy any significant resources.
Whether this is "good design" is subjective. I am merely offering a solution for the question asked.
How can I release an array created from a parameter?
I have function like
-(NSMutableArray*)composePhrase:(NSString*) phraseLiteral{
...
NSArray* wordLiterals=[phraseLiteral componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"[]"]];
...
[wordLiterals release];
}
and I always got problem with this release. Can anyone tell me how to make it right?
You need to understand the Object Ownership Policy.
You only gain the ownership automatically when the method name contains alloc, new or copy. Here, componentsSperatedByCharactersInSet: does not. Therefore, the returned wordLiterals is not owned by you. It's autoreleased. You shouldn't release it. It's released automatically when the autorelease pool is drained when the current event loop is complete.
If you want to keep the object, you retain it. Then you own it. When you no longer needs it, you release it.
The array returned by componentsSeparatedByCharactersInSet:... is autoreleased. This is true of pretty much all objects created like this -- ie, not via alloc or copy.
You are expected to retain it yourself if you want to keep hold of it. Otherwise it will evaporate at some unspecified future time (or if it doesn't it's not your responsibility).
Calling release on something you don't own will inevitably lead to grief down the line, so don't do it. In this case, since you seem to be using it only within the same scope, you can just let it take care of itself.
I'm getting weird EXC_BAD_ACCESS errors. I thought that I didn't need to retain objects if I was didn't need them after the method exited, but I want to double-check that. In the following, do I need to retain "tData"?
-(void)myMethod:(UITouch*)touch{
TouchData *tData = (TouchData *)CFDictionaryGetValue(datasByUITouch, touch);
[tData doSomething];
}
I think according to The Rules, what you're doing there doesn't require you to retain the tData object that scope. You're not doing an init, alloc, new or copy, instead you're using one of TouchData's methods to return some data, meaning that the method of TouchData that you're accessing is responsible for releasing the object.
Is the object being returned a CoreFoundation object? If so, see this from the Apple Docs (http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-SW1)
If you receive an object from any Core
Foundation function other than a
creation or copy function—such as a
Get function—you do not own it and
cannot be certain of the object’s life
span. If you want to ensure that such
an object is not disposed of while you
are using it, you must claim ownership
(with the CFRetain function). You are
then responsible for relinquishing
ownership when you have finished with
it.
Right, no need to retain in this method. Looks like touch was released before this method was called.
How was the CFDictionary created? If it wasn't created with instructions to retain values, then the dictionary won't retain touch. If that's the case, pass kCFTypeDictionaryValueCallBacks (CFValueCallBacks) as the valueCallBacks argument of the CFDictionaryCreate (or CFDictionaryCreateMutable).
I have two classes, a class that handles db connectivity and an entity class. The db class has an instance method called GetEntityByID:(int)entity_id. This method does a simple select statement, and creates an Entity class instance using an init method.
This works fine, however whoever calls GetEntityByID must remember to release it. Since GetEntityByID is not an "init" method, this doesn't seem right. How do I best handle memory management in this situation?
You can call autorelease in your GetEntityID method on the class to autorelease the instance if it is not otherwise retained.
Since the instantiation of the class is done within your DB connectivity class's method, the object that is returned the instance does not "own" it - your DB connectivity class. As of this, according to convention, you need to memory manage the instance:
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.
If the object sending the GetEntityID method wants to keep the object around, for example if it is to be used as an instance variable, then the returned object can be retained, preventing it from being deallocated at the end of the current event. If it is only being used locally, and doesn't need to be kept around after the current event, then the class doesn't have to do anything; it will be released by the autorelease pool at the end of the current event.
This article explains more about autorelease pools.
To autorelease the object returned in GetEntityID do something like this in GetEntityID:
... // cool stuff in GetEntityID
return [[entity_id retain] autorelease];
}
Have a look at this really nice article explaining Objective-C memory mangement in more detail.