2

I have NSZombieEnabled=YES set, and I want to do the following code

- (NSString*) udid
{
    if (udid == nil) 
    {
        udid = [[UIDevice currentDevice] uniqueIdentifier];
        NSLog(@"UDID=%@", udid);
    }
    return udid;
}

it turns out when udid is "released", it had been replaced with a Zombie, it's not nil. So I want to do something like

if (udid == nil || [udid isZombie])
{
    udid = [[UIDevice currentDevice] uniqueIdentifier];
    NSLog(@"UDID=%@", udid);
}

I tried [udid isKindOf:[NSZombie Class]], but NSZombie does not exist. So how can I tell is the udid object a Zombie now?

Zhao Xiang
  • 1,625
  • 2
  • 23
  • 40
  • Does the answer to [this question](http://stackoverflow.com/questions/535060/how-to-add-nsdebug-h-and-use-nszombie-in-iphone-sdk) help you? – Chris Frederick May 31 '11 at 05:08
  • @Chris, no it does not. I know how to enable `NSZombieEnabled`, thank you any way. – Zhao Xiang May 31 '11 at 05:21
  • 2
    Mike Ash wrote a helpful article about zombies: http://www.mikeash.com/pyblog/friday-qa-2011-05-20-the-inner-life-of-zombies.html – SSteve May 31 '11 at 05:35

2 Answers2

4

any message to a zombie will halt the program.

choose one which should not have side effects, such as self:

[udid self] // program will halt here if it's a zombie

any other approach to debugging or writing a program when zombie hunting seems pointless. that is, zombies do not exist in properly written programs, and they only exist under very specific debug-only conditions.

justin
  • 104,054
  • 14
  • 179
  • 226
3

A pointer to an object is never set to nil when the object is released. The pointer continues to point to the same memory location that it always did. That doesn't mean that whatever is now at that location is a valid object, however. For that reason, you should never use a pointer after you've released the object it points to. If you're going to continue to use that pointer, you should change its value so that it's either nil or points to some other (valid) object.

NSZombieEnabled is just a debugging tool that helps you find places in your code where you're accessing invalid objects. If you've found a place where you're doing that, you've found a bug in your code and you need to fix it, not tolerate it.

Change your code so that you properly set your udid pointer to nil once you've released it.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I have this in a singleton class, I have no idea why it's released, I may need to post another question on static object's memory management. So it's there any way to tell the `([udid isNotInited] || [udid isReleased])` without set it to nil? – Zhao Xiang May 31 '11 at 05:25
  • @Zhao, you could always override -release in your singleton class and put a breakpoint in there so that you can figure out where it's being released. IMO, however, the rest of your code should still follow the normal memory management rules and not rely on udid being a singleton. – Caleb May 31 '11 at 05:32
  • Caleb: your answer is "the correct thing to do", but does not answer the question. I'm trying to insert test/debug code to determine under what code-paths a variable becomes a zombie and the question remains: How do I do the equivalent of `if ([myObj isKindOfClass: [NSZombie Class]])...`? (One could see how this might also be useful in tutorial code.) Thanks! – Olie Mar 27 '14 at 18:02