views:

170

answers:

3

I have several objects in my app that can become nil at some point and I have methods that in theory are used to put these objects to nil.

But, if I try to put to nil an object that does not exist, the app will crash.

for example...

[object1 release];
object1 = nil;

//... and after that

[object1 removeFromSuperview]; // this will crash

Then I thought, why not testing to see if the object exists before removing...

if (object1 != nil)
 [object1 removeFromSuperview]; 
// this will crash too, because object1 cannot be tested for nil because it does not exist

How can I check if the object exists before testing if it is nil? something as

if (object1 exists( {
  if(object1 != nil))
    [object1 removeFromSuperview)
}

is this possible?

I ADDED THIS TO CLARIFY...

what I mean is this: imagine I have object1 declared on the header and initialized on the code. So, it exists and points to a valid reference. At some point, the object may be released, so the reference still points to an object but the object was freed. Even if I put the object to nil after releasing, I cannot do anything with it.

The problem is this: I have some methods that are asynchronous. One of them scans for some objects and remove them if they are found. I must check if the object exists and the reference points to a valid object before releasing it again. This is the point: how do I test if the object exists and its reference points to a valid existent object before releasing it again, to void releasing again an object that is already released and crash the app.

+2  A: 

In short, your question of determining if the pointer is still valid is going down the wrong path.

After you release an object, you must immediately set its value to null so that you no longer control it. If two methods are running asynchronously accessing the same object, they must be synchronized at that point so that releasing and setting to null happens at the same time in one thread before the other has a chance to interrupt.

Ed Marty
I have clarified the original question. thanks.
Digital Robot
+2  A: 

Are you just speculating, or have you actually tried this? Because in other programming languages, invoking a method on nil will cause a crash. In Objective-C this is not true. In Objective-C, you CAN send messages to nil without causing a crash. These messages simply have no effect.

In fact, you can be really obscene and do the following without a crash:

[(id)nil setTitle:@"Testing"];  // This will not cause a crash

If your app is crashing, it is not because you are messaging nil. It is possible, however, that you are failing to set a pointer to nil and you are messaging an object in memory that you do not own. Given the details you provided in your update, namely that you have an asynchronous thread accessing these objects, I think it is very likely you are sending messages to pointers whose object has already been released, but have not yet been set to nil.

glorifiedHacker
thanks. I am not speculating. The problem as I see now is not testing against nil is to test for the validity of a reference, before doing the test. Imagine a reference that points to a view that was freed. The reference is valid but the object it references too is not.
Digital Robot
+1  A: 

I have compared an object to nil before without any problems.

Lee Probert
thanks. The problem as I see now is not testing against nil is to test for the validity of a reference, before doing the test. Imagine a reference that points to a view that was freed. The reference is valid but the object it references too is not. Anyway thanks for your answer. +1 for the effort on helping :-)
Digital Robot