track “message sent to deallocated instance” via i

2019-05-06 02:38发布

问题:

In XCode 4.2, I need some help with Instruments to track down cause of EXC_BAD_ACCESS error. After enabling the NSZombie flag, I see the following on console when the app crashes on the device.

*** -[__NSArrayM removeObject:]: message sent to deallocated instance 0x8674e30

I used Instruments, but don't see the profile for Zombie. I used Allocations profile, but quickly got lost. I enabled ARC (in a hope to get rid of alloc/retain/release) for the app - but still have the same problem.

How do I use Instruments to track this down?

回答1:

Do you have any *UIScrollView*s in your view hierarchy and are you sending them messages like scrollToVisibleRect:animated:?

If so, try to pass NO for the animated parameter. It appears that iOS5 may have some issues with scroll views and embedded animations. The same exact crash you are seeing had been driving me crazy for a few days (with no call stack available) and I finally narrowed it down to the scroll view call. Hope it helps.



回答2:

I had the same problem. At first I have used the Raffaello Colasante's solution and passed NO to scrollRectToVisible:animated:. But then I've noticed that this method processed on another thread. You should check, whether you call [uitableview scrollRectToVisible: CGRectMake(0,0,1,1) animated:YES] on Main Thread (All ui actions should be performed on main thread). I change my code so to call it on Main Thread.

From:

//method called not from main thread
...
[someObjectInstance setOptionalActions:optActions];

To:

//method called not from main thread
...
dispatch_async(dispatch_get_main_queue(), ^{
    //now method called from main thread
    [someObjectInstance setOptionalActions:optActions];
});

Note: (setOptionalActions:) call -> (scrollRectToVisible:animated:)

Now problem fixed.

P.S. Instead of use Grand Central Dispatch(GCD), you can use another approach:

@implementation SomeObjectClass  
...
- (void) setOptionalActions:(NSArray *) actionsArray {
    ... // handling of array
    [myTableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];
}
...
@end

//method called not from main thread, but will be performed on main thread
[someObjectInstance performSelectorOnMainThread:@selector(setOptionalActions:) withObject:optionalActions waitUntilDone:NO];


回答3:

Profile or run with instruments(command+I) then use the Leaks tool.

Inside click on the leaks part and check the Gather Leaked memory content checkbox.

Good luck.



回答4:

Use the Command:

Shell malloc_history process_id memory

eg. Shell malloc_history process_id 0x11afab80

Enable Following for the same 1)MallocstackLogging 2) NsDebugEnabled 3)NSZombieEnabled

this will solve the problem



回答5:

Have a look at my answer on using the zombies profilier on the simulator. Basically you should be able to use the profilier by:

  1. Change the Run mode to profile.
  2. Select Zombies from the list.
  3. When it caches the zombie, double click on the stack trace on the right to see variaous parts of the objects lifecycle.