Objective-C - Test for object instance being dealloced/freed
Solution 1
You can't test whether an object has been dealloced since, obviously, the object isn't there to talk to anymore. If you set b
to nil when you release it (say, by doing self.b = nil
), though, you can test for nil and create the object then.
Solution 2
Since the variable b
is completely internal to class A
, and is not declared as @public
(the default is @protected
), the best way to know if b
has been deallocated is to release it and set the pointer to nil
. That way, you can just check if (b == nil)
and create a new instance if necessary.
The bigger question, however, is what the true nature and memory behavior of b
is. You state that "object B can be freed in memory low levels", but don't explain why. If you're using the standard idioms for retain-release in Objective-C, I would think that A would be the one to determine whether B should be deallocated, since it's creating a new instance. If you don't intend for A to make such decisions, allowing it to allocate a new B will lead to ownership confusion and memory bugs down the road.
If A is not in charge of B, and if you are on Leopard (or beyond) and have garbage collection enabled, what you may want is a zeroing weak reference. This is declared using __weak
before an instance variable declaration, and doesn't prevent the garbage collector from collecting the object it points to. (A "strong" reference is the default, and the garbage collector won't deallocate object it can trace from a root through only strong references.) Further, the GC will automatically set weak references to 0 for you if/when the object is deallocated.
Coming back to "the bigger question", unless b
is already a weak reference and GC is on, (and a few other conditions hold), the system will not automatically deallocate B for you. If the reason for deallocating b
is that instances of B grow over time, (such as a cache of dispensable items), it would be much better to have a way to empty B. For example, mutable collections in Foundation have a -removeAllObjects
method. Such an approach would avoid most of the confusion about whether b
still exists, and is much more efficient than repeatedly (de)allocating objects.
Solution 3
If you retain b properly, it will not be deallocated in low memory conditions.
That is, unless you are deallocating it yourself, in which case it is important that you manually remove any references to it before you do so (by replacing it with nil)
In that case, simply testing it for the nil value will do:
if (nil == b)
{
reallocate b;
}
If it seems like your objects are being deallocated automatically, then you need to review your code to check you have retained it sufficiently.
jlpiedrahita
Updated on June 24, 2022Comments
-
jlpiedrahita almost 2 years
There's some way to test for an objective-c instance for being dealloced/freed (retain count == 0)??
By example, object A have a reference (pointer) to object B, but object B can be freed in memory low levels, how i test reference B to be sure it was dealloced??
@interface A : NSObject { B b; } @implementation A { - (void) someAction:(id) sender { //is b previously dealloced?? if ..... ???? { b = [[B alloc] init]; } // continue } }
Thanks!!
-
Quinn Taylor almost 15 yearsThat won't work for a test in code to see if the object has been deallocated. At best, it would help debug that the retain-release code related to B is (probably) correct.
-
Chuck almost 15 yearsThe tags say Cocoa Touch, so he's not on Leopard.
-
Quinn Taylor almost 15 yearsOne of the tags is also "Cocoa", and the question didn't specify iPhone, so I though it best to be general and qualify with "if" to be helpful to those who may be on Leopard.
-
jlpiedrahita almost 15 yearsthat's the problem, i don't release the object explicitly, it's released by framework classes and this don't happen to predictable times (ex. didReceiveMemoryWarning: method calls) so i need to test if my reference (pointer) is still pointing to a valid instance, if not, alloc and init a new one.
-
Chuck almost 15 yearsWhat framework class is releasing this class's instance variable? Why doesn't this class own its own ivar? I think you might need to provide more info in the question. As Alex said, your attributes shouldn't be mysteriously disappearing.
-
Dan Rosenstark over 12 yearspretty sure calling a message on a dealloced instance does NOT throw a normal exception bur rather a sigbart.