Objective-C - check that an instance of an object is freed / freed

Is there some way to check the objective-c instance for release / release (keep count == 0) ??

For example, object A has a link (pointer) to object B, but object B can be freed at low memory levels, how do I test link B to make sure it has been canceled ??

@interface A : NSObject { B b; } @implementation A { - (void) someAction:(id) sender { //is b previously dealloced?? if ..... ???? { b = [[B alloc] init]; } // continue } } 

Thanks!!

+7
objective-c cocoa-touch cocoa
source share
6 answers

You cannot check if the object was deleted, because obviously the object no longer exists. If you set b to zero when you release it (for example, by doing self.b = nil ), you can check for nil and then create an object.

+11
source share

If you set the environment variable NSZombieEnabled , then the freed objects become instances of NSZombie . These throws, the next time they appear, cause your code to crash and write — exactly what you need to debug this situation.

http://www.cocoadev.com/index.pl?DebuggingAutorelease

Update : for Xcode 4.0 see How to enable NSZombie in Xcode?

+13
source share

Since the variable b completely internally class A and not declared as @public (the default is @protected ), the best way to find out if b is freed is to free it and set the pointer to nil . That way you can just check if (b == nil) and create a new instance if necessary.

A more general question is what is the true nature and behavior of memory b . You state that “Object B can be freed at low levels of memory,” but do not explain why. If you use standard idioms to save-release in Objective-C, I would think that A will determine if B should be freed as it creates a new instance. If you do not intend for A to make such decisions, allowing him to allocate a new B, this will lead to ownership confusion and memory errors in the future.

If A is not responsible for B, but if you are on Leopard (or beyond) and turn on garbage collection, then you may need to reset the weak links . This is declared using __weak before declaring the instance variable and does not prevent the garbage collector from collecting the object it points to. (A strong link is the default, and the garbage collector does not free an object that it can only trace from the root through strong links.) In addition, GC automatically sets weak links to 0 for you if / when the object is redistributed.

Returning to the “bigger question”, if b already a weak benchmark and GC is turned on (and a few more conditions), the system will not automatically release you from B. If the reason for freeing b is because instances of B grow over time (for example, cache of dispensable elements), it would be much better to have a way to empty B. For example, mutable collections in Foundation have -removeAllObjects . Such an approach would have avoided more confusion as to whether b still exists and is much more efficient than repeatedly (de) selecting objects.

+3
source share

If you save b correctly, it will not be freed in low memory conditions.

That is, if you do not release it yourself, in this case it is important that you manually delete any links to it before you do it (replacing it with zero)

In this case, a simple test for the nil value will do:

  if (nil == b) { reallocate b; } 

If it seems to you that your objects are automatically freed, you need to look at your code to verify that you have saved it enough.

+2
source share

You can try putting NSLog messages in the dealloc method of objects. This will at least tell you when the object will be released.

0
source share

will try-catch work?

  @try { [b description]; // test it... } @catch (NSException * e) { NSLog(@"Exception: %@", e); } @finally { NSLog(@"finally"); } 
-3
source share

All Articles