2013-03-16 66 views
0

我有NSMutableArray alloc和释放问题。见下面的代码:的iOS NSMutable阵列释放行为

NSMutableArray *enemiesToDeleteArray = [NSMutableArray arrayWithCapacity:5]; 
... 
else if ([enemy isActive] && !CGRectIntersectsRect(fieldOfView, enemyRect)) 
     { 
      [enemiesToDeleteArray addObject:enemy]; 
     } 
... 
[enemiesToDeleteArray removeAllObjects]; 
[enemiesToDeleteArray release]; 

上面的代码在运行中崩溃。使用符号调试中断错误“objc_release”或“malloc_break_error”。下面我加回溯的发生objc_release错误:

* thread #1: tid = 0x1c03, 0x01e140a5 libobjc.A.dylib`objc_release + 21, stop reason = EXC_BAD_ACCESS (code=1, address=0xa0020010) 
    frame #0: 0x01e140a5 libobjc.A.dylib`objc_release + 21 
    frame #1: 0x01e14bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555 
    frame #2: 0x023c6468 CoreFoundation`_CFAutoreleasePoolPop + 24 
    frame #3: 0x002effc1 QuartzCore`CA::AutoreleasePool::~AutoreleasePool() + 19 
    frame #4: 0x002ff35f QuartzCore`CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long) + 251 
    frame #5: 0x002ff75f QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 161 
    frame #6: 0x023e3376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 
    frame #7: 0x023e2e06 CoreFoundation`__CFRunLoopDoTimer + 534 
    frame #8: 0x023caa82 CoreFoundation`__CFRunLoopRun + 1810 
    frame #9: 0x023c9f44 CoreFoundation`CFRunLoopRunSpecific + 276 
    frame #10: 0x023c9e1b CoreFoundation`CFRunLoopRunInMode + 123 
    frame #11: 0x0312b7e3 GraphicsServices`GSEventRunModal + 88 
    frame #12: 0x0312b668 GraphicsServices`GSEventRun + 104 
    frame #13: 0x009d0ffc UIKit`UIApplicationMain + 1211 
    frame #14: 0x000c81f6 MyAPP`main(argc=1, argv=0xbffff36c) + 134 at main.m:14 
    frame #15: 0x00001fa5 MyAPP`start + 53 

和malloc_break_error回溯:

MyAPP(18609,0xac98ea28) malloc: *** error for object 0x112dee40: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 

(lldb) bt 
    * thread #1: tid = 0x1c03, 0x97be7815 libsystem_c.dylib`malloc_error_break, stop reason = breakpoint 1.1 
     frame #0: 0x97be7815 libsystem_c.dylib`malloc_error_break 
     frame #1: 0x97be8d51 libsystem_c.dylib`free + 346 
     frame #2: 0x023c5ea4 CoreFoundation`-[__NSArrayM dealloc] + 276 
     frame #3: 0x01e159ff libobjc.A.dylib`-[NSObject release] + 47 
     frame #4: 0x01e140d5 libobjc.A.dylib`objc_release + 69 
     frame #5: 0x01e14bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555 
     frame #6: 0x023c6468 CoreFoundation`_CFAutoreleasePoolPop + 24 
     frame #7: 0x002effc1 QuartzCore`CA::AutoreleasePool::~AutoreleasePool() + 19 
     frame #8: 0x002ff35f QuartzCore`CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long) + 251 
     frame #9: 0x002ff75f QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 161 
     frame #10: 0x023e3376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 
     frame #11: 0x023e2e06 CoreFoundation`__CFRunLoopDoTimer + 534 
     frame #12: 0x023caa82 CoreFoundation`__CFRunLoopRun + 1810 
     frame #13: 0x023c9f44 CoreFoundation`CFRunLoopRunSpecific + 276 
     frame #14: 0x023c9e1b CoreFoundation`CFRunLoopRunInMode + 123 
     frame #15: 0x0312b7e3 GraphicsServices`GSEventRunModal + 88 
     frame #16: 0x0312b668 GraphicsServices`GSEventRun + 104 
     frame #17: 0x009d0ffc UIKit`UIApplicationMain + 1211 
     frame #18: 0x000c81f6 MyAPP`main(argc=1, argv=0xbffff36c) + 134 at main.m:14 
     frame #19: 0x00001fa5 MyAPP`start + 53 

请解释我这样的人,我究竟做错了什么?

+0

正如其他人所指出的那样,简单地删除调用'release'。你也可以删除对'removeAllObjects'的调用 - 在释放期间''NSMutableArray'实例会自动处理它。 – jlehr 2013-03-16 15:31:27

回答

4

你不应该释放enemiesToDeleteArray可言。它将在当前作用域的末尾自动释放。你完全没有使用alloc,所以这个对象是自动管理的。

+0

但是为什么?我的意思是,在分配数组时没有赋予autorelease的属性。 – PiotrCh 2013-03-16 14:37:39

+1

@CrazyBucket我更新了我的回复。 – bioffe 2013-03-16 14:38:26

+2

你'新',''alloc','保留',或'复制'NSMutableArray'?没有?那么不要“释放”它! – 2013-03-16 14:38:42

2

NSMutableArray *enemiesToDeleteArray = [NSMutableArray arrayWithCapacity:5];返回一个自动释放的情况下,并留下初始化之后被清理了一些时间。现在指针enemiesToDeleteArray指向未定义的内存。你需要做的:

enemiesToDeleteArray = [[NSMutableArray arrayWithCapacity:5] retain]; 

enemiesToDeleteArray = [[NSMutableArray alloc] initWithCapacity:5]; 
+0

不一段时间后。 CS是一门科学,我们以后不会有魔法。 – bioffe 2013-03-16 14:39:51

+2

我们用autoreleasing,其实。从这个方法的范围来看,释放将被系统调用的时间是未知的。 – 2013-03-16 14:40:23

+0

同意。从这种方法的角度来看,它只能假设“比我的回归晚了一段时间”。这正是如何思考它。 – 2013-03-16 14:41:40