2011-10-05 5 views
0

저는 아이들을 위해 iOS에서 기본적인 추측 게임을 만들고 있는데, 앱의 수명주기 전반에 걸쳐 객체를 만들고 릴리스해야하는 방법에 대한 기본적인 이해가 부족하다고 생각합니다. 유지 및 릴리스 사이클을 읽고 있었지만 내 문제는 앱의 근본적인 아키텍처와 더 관련이 있으며 앱의 몇 가지 주요 개체를 인스턴스화하고 죽이려고 시도하는 방법이 잘못되었다고 생각합니다.기본 IOS OOP - 구조 및 구현

문제는 두 가지 특정 클래스를 중심으로합니다.

나는 게임을 실행하는 데 필요한 모든 정보를 보유하도록 설계된 게임 클래스를 가지고 있습니다. 초기화 될 때, 다양한 실마리와 같은 문자열을 포함하는 배열을 가리키는 모든 인스턴스 변수를 보유합니다. 기본적으로 게임에 필요한 모든 데이터의 컨테이너입니다.

게임 클래스의 인스턴스와 인스턴스를 생성하고 쿼리하여 게임 개체에 포함 된 다양한 요소를 화면에 표시하도록하는 게임보기 컨트롤러가 있습니다.

이것은 완벽하게 작동합니다. 사용자가 새 게임을 시작하면 게임 클래스의 새 인스턴스가 할당되고 초기화되어 사라집니다.

새 게임을 생성 할 때 문제가 발생합니다. 이것은 여러 가지 방법으로 발생합니다. 사용자가 게임을 끝내고 다른 게임을 시작하거나 사용자가 현재 게임을 종료 한 후 새 게임을 시작합니다.

내 생각에, 나는 게임 객체를 해제하고 할당하고 초기화 할 것이다. 그러나 장치를 실행하고 프로파일 러를보고 게임 객체가 전혀 릴리스되지 않았 음을 알았습니다. 아직 거기에 있으며 게임의 각 인스턴스화는 포인터가없는 이전 객체와 함께 새 게임 객체를 만듭니다. 그것에.

코드를 둘러 보면서 Game 클래스에 dealloc 메서드를 구현하지 않은 것을 알았지 만, 그렇게하려고하면 이전에 릴리스 된 버전을 릴리스하려고하기 때문에 앱이 다운되고 목적.

내가하려는 것은 이상적으로 오래된 게임 개체를 제거하거나 새로운 게임이 시작될 때마다 이전 게임 개체를 덮어 쓰는 것입니다.

그러나이 방법이 잘못 되었습니까? 내가 완전히 다른 방식으로해야할까요? 게임 클래스의 인스턴스를 하나만 만들고 그 클래스 내부의 메소드를 다시 작성하여 새로운 게임이 시작될 때마다 새로운 단서 세트를 생성하고 GameViewController가 알려줄 때 등?

이렇게하는 것이 가장 좋은 방법입니까?

#import "GameViewController.h" 

@implementation GameViewController 

@synthesize game = _game; 


-(void)startNewGameOfLevel:(NSInteger)level 
    { 
     if(!_game) 
     { 
      Game *g = [[Game alloc]initGamewithLevel:level]; 
      [self setGame:g]; 
      [g release]; g = nil; 
     } 

     [self set_currentlevel:[_game _currentLevel]]; 

     // set up popover to show the rounds goal letter 
     [self setUpPopOver]; 

    } 

-(void)quitTheCurrentGameAndStartNewGame 
{ 
    [_game release]; _game = nil; 
    [self clearGamePlayingField]; 
    animationStepIndex = 0; 
    [self startNewGameOfLevel: _currentlevel]; 
} 

게임 클래스 (요약 된) 지정 초기화와 :

그래서 당신이 코드는 게임 클래스의 인스턴스가 생성 된 GameViewController, 아래, 내가 뭐하는 거지의 생각이있어 게임 클래스의 :

#import "Game.h" 


    @implementation Game 

    @synthesize arrayOfLowerCaseLetters = _arrayOfLowerCaseLetters; 
    @synthesize arrayOfPhrases= _arrayOfPhrases; 

    @synthesize goalLetter = _goalLetter; 
    @synthesize goalPhrase = _goalPhrase; 
    @synthesize gameLetterPool = _gameLetterPool; 

    @synthesize _indexForGoalLetter, _numberOfLevelsInGame, _currentLevel, _numberOfWhackHoles, _numberOfLettersInGameLetterPool; 

    -(id)initGamewithLevel:(NSInteger)level 
    { 
     [super init]; 

     //create an array of lower case letters. These will 
     //contain the full alphabet of all possible letters 

     NSArray *arrayOfLCLetters = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", @"d",@"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"qu", @"r", @"s", @"t", @"u", @"v", @"w", @"x",@"y", @"z",@"ch", @"sh", @"th", nil]; 
     [self setArrayOfLowerCaseLetters: arrayOfLCLetters]; 
     [arrayOfLCLetters release];arrayOfLCLetters = nil; 

     //create an array of phrases. 
     // These must correspond with each of the letters. e.g. a = apple. 

     NSArray *phrases= [[NSArray alloc ] initWithObjects: 
          @"apple", 
          @"butterfly", 
          @"cat", 
          @"dog", 
          @"egg", 
          @"frog", 
          @"ghost", 
          @"horse", 
          @"igloo", 
          @"jam", 
          @"kite", 
          @"leaf", 
          @"moon", 
          @"nut", 
          @"orange", 
          @"pig", 
          @"queen", 
          @"rabbit", 
          @"snake", 
          @"tree", 
          @"umbrella", 
          @"van", 
          @"water", 
          @"x-ray", 
          @"yak", 
          @"Zebra", 
          @"chair", 
          @"shoes", 
          @"thumb", 

          nil]; 
     [self setArrayOfPhrases:phrases]; 
     [phrases release]; phrases = nil; 


     //choose a random number to be the index reference for 
     // each goal letter and goal phrase. 
     [self set_indexForGoalLetter:(arc4random()%[_arrayOfLowerCaseLetters count])]; 
     NSLog(@"index for goal letter is:, %i", _indexForGoalLetter); 

     //set Goal letter and goal phrase 
     [self setGoalLetter: [_arrayOfLowerCaseLetters objectAtIndex: _indexForGoalLetter]]; 
     [self setGoalPhrase: [_arrayOfPhrases objectAtIndex:_indexForGoalLetter ]]; 

     //set current level 
     [self set_currentLevel: level]; 
     //[self set_currentLevel: 2]; 


     //set number of whackholes by level 
     [self set_numberOfWhackHoles: [self numberOfWhackHolesByLevel:_currentLevel]]; 

     //generate size of Letter pool by level 
     [self set_numberOfLettersInGameLetterPool:[self numberOfLettersInLetterPoolbyLevel:_currentLevel]]; 

     //////////////////////////// 
     /// Game letter pool 
     /////////////////////////// 

     //set up array ton hold the pool of letters 
     NSMutableArray *gp = [[NSMutableArray alloc] initWithCapacity:_numberOfLettersInGameLetterPool]; 
     [self setGameLetterPool: gp]; 
     [gp release];gp = nil; 

     //add the goal letter to this pool 
     [_gameLetterPool addObject:_goalLetter]; 

     int i = 1; 

     while (i < _numberOfLettersInGameLetterPool) { 
      NSString *letter = [_arrayOfLowerCaseLetters objectAtIndex:(arc4random()%[_arrayOfLowerCaseLetters count])]; 
      if ([_gameLetterPool containsObject:letter] == false) 
      { 
       [_gameLetterPool addObject:letter]; 
       i++; 
      } 

     } 

     NSLog(@"********** Game created ***************"); 
     NSLog(@"pool of letters is: %@", [_gameLetterPool description]); 
     NSLog(@"****************************************"); 
     NSLog(@"current goal letter is: %@", _goalLetter); 
      NSLog(@"****************************************"); 
     NSLog(@"current goal phrase is: %@", _goalPhrase); 
      NSLog(@"****************************************"); 

     return self; 
    } 

-(void)dealloc 
{ 
    [super dealloc]; 
    [_arrayOfLowerCaseLetters release]; _arrayOfLowerCaseLetters = nil; 
    [_arrayOfPhrases release]; _arrayOfPhrases = nil; 
    [_goalLetter release];_goalLetter = nil; 
    [_goalPhrase release]; _goalPhrase = nil; 
    [_gameLetterPool release];_gameLetterPool = nil; 
} 

답변

2

번호를 하나의 문제는 [super dealloc] 당신이 -dealloc에서 할 절대 마지막 일이 될해야한다는 것입니다. 이것은 실제로 메모리를 해제하는 NSObject의 dealloc 메소드이기 때문에 다시 돌아올 때쯤에는 인스턴스 변수 포인터가 이미 가비지 일 수 있습니다.

다른 문제 : 초기화에서

는 슈퍼 객체가 초기화에 다른 자기 포인터를 반환 할 수있다 self = [super init];을한다.

startNewGameOfLevel:quitTheCurrentGameAndStartNewGame은 재산이 아니라 베어 인스턴스 변수를 사용해야합니다.

-(void)startNewGameOfLevel:(NSInteger)level 
    { 
     if(![self game]) 
     { 
      Game *g = [[Game alloc]initGamewithLevel:level]; 
      [self setGame:g]; 
      [g release]; g = nil;// g = nil, not necessary when it's about to go out of scope 
     } 

     [self set_currentlevel:[[self game] _currentLevel]]; // don't use _ to start methods - Apple reserves this convention 

     // set up popover to show the rounds goal letter 
     [self setUpPopOver]; 

    } 

-(void)quitTheCurrentGameAndStartNewGame 
{ 
    [self setGame: nil]; 
    [self clearGamePlayingField]; 
    animationStepIndex = 0; 
    [self startNewGameOfLevel: _currentlevel]; 
} 

아마 코드의 몸에 다른 문제가 있습니다 - 당신은 정적 분석이 가능하게 빌드해야합니다 - 그것은 그들 중 많은 사람들을 잡을 것입니다.