I'm trying to debug some ARC code, and it'd be really helpful if i could find out when an object of a certain class is added to the autorelease pool (not when it is actually autoreleased down the track).
Is this possible, eg with a breakpoint? Or by overwriting the 'autorelease' method and putting a breakpoint in it? Any suggestions?
-- edit --
The problem is that i've got an infrequent crash occurring where a custom subclass of UIView is autoreleased on a background thread, which crashes because UIView's cannot be dealloc'd on a background thread. The trace looks like below:
0 libsystem_kernel.dylib __pthread_kill + 8
1 libsystem_c.dylib pthread_kill + 54
2 libsystem_c.dylib abort + 94
3 libc++abi.dylib abort_message + 46
4 libc++abi.dylib default_terminate() + 24
5 libobjc.A.dylib _objc_terminate + 146
6 libc++abi.dylib safe_handler_caller(void (*)()) + 76
7 libc++abi.dylib operator delete(void*)
8 libc++abi.dylib __cxa_throw + 122
9 libobjc.A.dylib objc_exception_throw + 94
10 CoreFoundation +[NSException raise:format:]
11 Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 90
12 MYAPP MySuperclass.m line 156 -[MySuperclass dealloc]
13 MYAPP MyClass.m line 41 -[MyClass dealloc]
14 ... libobjc.A.dylib _objc_rootRelease + 36
15 libobjc.A.dylib objc_release + 38
16 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 224
17 libobjc.A.dylib _objc_autoreleasePoolPop + 12
18 CoreFoundation _CFAutoreleasePoolPop + 18
19 libdispatch.dylib _dispatch_worker_thread2 + 338
20 libsystem_c.dylib _pthread_wqthread + 294
Navigate to a line in your code where you want execution to pause, then click the gutter or line number in the source editor to set a breakpoint. Xcode displays a breakpoint icon to indicate the location. Drag a breakpoint up or down to move it to another location; drag it away from the gutter to remove it.
An autorelease pool stores objects that are sent a release message when the pool itself is drained. Important. If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks.
This might not help with your problem, but I think it answers your original question:
You can add a symbolic breakpoint on [NSObject autorelease]
and then set a condition to match your class. If your running on a device $r0
should hold the pointer to the receiving object. You need to do some casting to make the condition work: (BOOL)[(id)$r0 isKindOfClass:[NSArray class]]
breaks whenever an NSArray
is added to the autoreleasepool. Note that everything will be running very slow as the debugger has to break on every autorelease and check the condition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With