Я программист начального уровня, пытающийся сделать игровое приложение для iphone, и я до сих пор сталкивался с возможной проблемой управления памятью (exc_bad_access) моей программы. Я искал и читал десятки статей, касающихся управления памятью (включая документы Apple), но я до сих пор не могу понять, что именно не так с моими кодами. Поэтому я был бы очень признателен, если бы кто-нибудь помог мне разобраться в том беспорядке, который я устроил для себя.
//in the .h file
@property(nonatomic,retain) NSMutableArray *fencePoleArray;
@property(nonatomic,retain) NSMutableArray *fencePoleImageArray;
@property(nonatomic,retain) NSMutableArray *fenceImageArray;
//in the .m file
- (void)viewDidLoad {
[super viewDidLoad];
self.gameState = gameStatePaused;
fencePoleArray = [[NSMutableArray alloc] init];
fencePoleImageArray = [[NSMutableArray alloc] init];
fenceImageArray = [[NSMutableArray alloc] init];
mainField = CGRectMake(10, 35, 310, 340);
..........
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(gameLoop) userInfo:nil repeats:YES];
}
Таким образом, в основном, игрок касается экрана, чтобы установить заборы / столбы
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(.......) {
.......
}
else {
UITouch *touch = [[event allTouches] anyObject];
currentTapLoc = [touch locationInView:touch.view];
NSLog(@"%i, %i", (int)currentTapLoc.x, (int)currentTapLoc.y);
if(CGRectContainsPoint(mainField, currentTapLoc)) {
if([self checkFence]) {
onFencePole++;
//this 3 set functions adds their respective objects into the 3 NSMutableArrays using addObject:
[self setFencePole];
[self setFenceImage];
[self setFencePoleImage];
.......
}
}
else {
.......
}
}
}
}
Функция setFence (setFenceImage и setFencePoleImage похожи на это)
-(void)setFencePole {
Fence *fencePole;
if (!elecFence) {
fencePole = [[Fence alloc] initFence:onFencePole fenceType:1 fencePos:currentTapLoc];
}
else {
fencePole = [[Fence alloc] initFence:onFencePole fenceType:2 fencePos:currentTapLoc];
}
[fencePoleArray addObject:fencePole];
[fencePole release];
и всякий раз, когда я нажимаю кнопку в игре, вызывается endOpenState, чтобы убрать все лишние изображения (забор / столбы) на экране, а также удалить все существующие объекты в 3 NSMutableArray. Задача состоит в том, чтобы удалить все объекты в NSMutableArrays, но сохранить сам массив, чтобы его можно было использовать позже.
-(void)endOpenState {
........
int xMax = [fencePoleArray count];
int yMax = [fenceImageArray count];
for (int x = 0; x < xMax; x++) {
[[fencePoleImageArray objectAtIndex:x] removeFromSuperview];
}
for (int y = 0; y < yMax; y++) {
[[fenceImageArray objectAtIndex:y] removeFromSuperview];
}
[fencePoleArray removeAllObjects];
[fencePoleImageArray removeAllObjects];
[fenceImageArray removeAllObjects];
........
}
Здесь происходит сбой в функции checkFence.
-(BOOL)checkFence {
if (onFencePole == 0) {
return YES;
}
else if (onFencePole >= 1 && onFencePole < currentMaxFencePole - 1) {
CGPoint tempPoint1 = currentTapLoc;
CGPoint tempPoint2 = [[fencePoleArray objectAtIndex:onFencePole-1] returnPos]; // the crash happens at this line
if ([self checkDistance:tempPoint1 point2:tempPoint2]) {
return YES;
}
else {
return NO;
}
}
else if (onFencePole == currentMaxFencePole - 1) {
......
}
else {
return NO;
}
}
Итак, проблема в том, что все работает нормально, пока checkFence не будет вызван во 2-й раз после вызова endOpenState. Так что это как tap_screen -> tap_screen -> press_button_to_call_endOpenState -> нажмите экран -> tap_screen -> crash
Я думаю о том, что fencePoleArray испортился, когда я использовал [fencePoleArray removeAllObjects], потому что он не падает, когда я закомментирую его. Было бы здорово, если бы кто-нибудь объяснил мне, что пошло не так. И заранее спасибо.