저는 초급 수준의 프로그래머로서 아이폰 용 게임 응용 프로그램을 만들려고 노력 중이며 지금까지 프로그램의 메모리 관리 (exc_bad_access)에 문제가 발생했습니다 . 나는 수십개의 기사를 읽고 (사과의 문서를 포함하여) 메모리 관리에 관해서 읽었지 만, 나는 여전히 나의 코드에 정확히 무엇이 잘못된 것인지 알 수 없다. 누군가가 나 자신을 위해 만든 엉망을 정리하는 데 도움이된다면 정말 감사 할 것입니다.내 게임 모델의 메모리 관리 문제에 대한 도움이 필요합니다.
//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;
}
}
여기의 문제는 endOpenState가 호출 된 후 checkFence가 두 번째로 호출 될 때까지 모든 것이 올바르게 작동합니다. 그래서 그와 같은 tap_screen -> tap_screen -> press_button_to_call_endOpenState -> 탭 화면 -> tap_screen -> 충돌
는내가 생각하고있어의 내가 사용하는 경우 fencePoleArray이 엉망이있어이다 [fencePoleArray는 removeAllObjects]이 때 충돌하지 않기 때문에 나는 그것을 주석 처리한다. 누군가가 나에게 무엇이 잘못되었는지 설명 할 수 있다면 정말 좋을 것입니다. 그리고 미리 감사드립니다.
당신이 endOpenState에 onFencePole 및 currentMaxFencePole를 재설정하고 있습니까? 그렇지 않으면 코드가 (이제 비어있는) 배열의 끝에서 액세스 할 수있는 것처럼 보입니다. – user308405
그것은 예외를 던질 것입니다, 그렇지 않습니까? – zoul
예 onFencePole 및 currentMaxFencePole을 재설정했습니다. – Treon