The problem you describe could be one of a couple of things; you may be over-releasing an object or you might be corrupting memory. If you corrupt memory -- corrupt the first few bytes of an object, specifically -- then it can easily manifest as a crash during an autorelease pool drain (or any other message).
That the crash happens on a device, but not the simulator, points to memory corruption, as well. The architecture of the device [ARM] vs. the simulator [i386] is quite different and there are any of a number of issues that may be at play.
Typically, it doesn't manifest itself quite so consistently.
First, post the backtrace of the crash. It might help.
Secondly, do you do any kind of raw malloc
calls? Or filling buffers with data? The most common cause of such crashes is running past the end of a buffer.
#0 0x31ac8bc8 in _cache_fill ()
#1 0x31acaf8e in lookUpMethod ()
#2 0x31ac8780 in _class_lookupMethodAndLoadCache ()
#3 0x31ac859a in objc_msgSendSuper_uncached ()
#4 0x328014f0 in -[__NSArrayReverseEnumerator dealloc] ()
(The above was added after the OP fixed the problem, but -- for the archive)
That crash trace is a classic signature of memory corruption. Namely, the isa
pointer -- the first pointer's worth of bytes in an object that points at the Class of the instance -- was stomped. This typically happens when the you overrun a buffer of memory in the allocation before the object. If it is just a couple of byte overrun, then the behavior between different platforms may differ since the malloc quanta -- the real size of the allocations (you ask for 90 bytes on one platform and you might get 96. Another? 128) -- differ between platforms and, even, releases.
In particular, the isa was stomped with a value that looked enough like a pointer that the runtime dereferenced the garbage value and then tried to treat the resulting location as the Class's method table.
Any time you see a crash that is a few frames deep into one of the objc_msgSend*()
functions, it is quite likely memory corruption and, if so, it will almost always be a buffer overflow.
Since it is easy to do, it is still a good idea to do a test pass with zombie detection to catch the "sometimes it is really just an over-release cases".
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…