I encountered such a problem recently, but I didn't pay attention to it before. I created a project and added a class. The file structure is like this.
Then write such a short program to run
-(Void) viewdidload {[Super viewdidload]; test * testobj = [[test alloc] init]; nslog (@ "% d before release", [testobj retaincount]); [testobj release]; nslog (@ "% d after release", [testobj retaincount]);}
Obviously, the retaincount count should be 0, but why is the retaincount count still 1? When we perform the release operation twice, the program crashes;
Then we can print the testobj object.
-(Void) viewdidload {[Super viewdidload]; test * testobj = [[test alloc] init]; nslog (@ "% d before release", [testobj retaincount]); nslog (@ "testobj release pointing to --> % @", testobj); [testobj release]; nslog (@ "% d after release", [testobj retaincount]); nslog (@ "testobj release pointing to --> % @", testobj );}
They point to the same address;
When testobj is in alloc, a space is applied to the heap, and its retaincount is counted as 1. After the release, the space indicated by testobj is destroyed and does not exist. In this case, testobj is a wild pointer. Calling [testobj retaincount] is an insecure method;
Then we add testobj = nil after adding a line of code [testobj release;
-(Void) viewdidload {[Super viewdidload]; test * testobj = [[test alloc] init]; nslog (@ "% d before release", [testobj retaincount]); nslog (@ "testobj release pointing to --> % @", testobj); [testobj release]; testobj = nil; nslog (@ "% d after release ", [testobj retaincount]); nslog (@ "testobj release pointing to --> % @", testobj );}
Alas, you should understand it here. After [testobj release], testobj still points to, but the space originally pointed to by testobj has been destroyed, but it still exists, by setting this step to nil, we will not point to the original address. We should remember the role of the viewdidunload function. It is doing this job. When we declare an object attribute, set this attribute to nil in viewdidunload;