2010-01-16 2 views
0

저는 아이폰 개발을 처음 사용합니다. 나는 "구식 학교"입니다 - 프로그래밍 할 때 프로 시저 등을 사용하는 것을 힘들었습니다. 요즘에는 모든 것이 객체 지향이지만 내 스타일은 항상 그렇듯이 있습니다. 그 점을 명심하십시오. 저의 프로젝트는 작고 사실 개념의 증거입니다.Plist Dictionary에서 임의의 단어 표시 - 메모리 누수?

아래 프로그램은 30 초마다 내 응용 프로그램에서 Dictionary.plist에 저장된 내 이름 데이터베이스 목록에서 임의의 아기 이름을 읽습니다. 그런 다음 아이폰 화면에이 이름이 표시됩니다.

아래 코드의 관련 부분을 모두 볼 수 있습니다. 어떻게됩니까? - 타이머를 빠르게 실행하면 타이머가 빨라지므로 결과적으로 메모리가 부족한 것처럼 보입니다. 다음 무작위 아기 이름 대신에. 이 문제는 데이터베이스 파일을 읽을 때마다 닫히지 않아서입니다.

어쨌든, 누군가 내 코드를 고려하여 (위의 내 의견을 고려해 볼 수 있음) 표시를 중단하려면 추가해야 할 사항을 말해주십시오 ???? 많은 실행 후 .. 내가 할 수있는 또 다른 방법을 알아낼을 couldnt으로 난 단지 ShowNextName에서 파일을 매번 개방하고

..

나는 이것의 시작 부분에 변수를 사용하는 그것하지 좋은 스타일을 알고 코드 등 글로벌하지만 거기에 구조 조정 또는 무언가를 추가하는 "충돌"또는 너무 많은 실행 후 조금 우스운 방법을 추가 할 수있는 방법이 있습니다 ...

나는 그것을 감사하겠습니다. 감사.

#import "BabyNameViewController.h" 

@implementation BabyNameViewController 


NSDictionary *dictionary; 
NSString *name; 

int nameCount = 0; 
int RecordIndex = 0; 


- (void)ShowNextname; 
{ 
    NSString *path = [[NSBundle mainBundle] bundlePath]; 
    NSString *finalPath = [path stringByAppendingPathComponent:@"Dictionary.plist"]; 
    NSArray* plistArray = [NSArray arrayWithContentsOfFile:finalPath]; 

    // Generate a random number between 0 and (the number of records-1) - used as a random index! 

    RecordIndex=arc4random()%[plistArray count]; 


    // Select and display currently selected record from the array. 
    dictionary = [plistArray objectAtIndex:RecordIndex]; 
    name = [dictionary objectForKey:@"name"]; 

    [nameLabelOutlet setText: [NSString stringWithFormat: @"Random Baby Name is: %@", name]]; 

} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

// Initial App entry point - startup code.. 


// Open the dictionary to count the number of names and store it for later use. 
NSString *path = [[NSBundle mainBundle] bundlePath]; 
NSString *finalPath = [path stringByAppendingPathComponent:@"Dictionary.plist"]; 
NSArray* plistArray = [NSArray arrayWithContentsOfFile:finalPath]; 
nameCount = [plistArray count]; 

// Generate random name from database 
[self ShowNextname]; 

// Start up the nameUpdate timer. 
[NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(nameUpdate) userInfo:nil repeats:YES]; 

}

-(void) nameUpdate { 
    [self ShowNextname]; 
} 

답변

1

문제는 30 초마다 당신은 새로운 배열로 PLIST를 다시로드되어있을 수 있습니다. 당신이해야 할 일은 viewDidLoad에서 객체의 인스턴스 변수 (뷰 컨트롤러 클래스)에 plist를로드 한 다음 showNextName에서 해당 인스턴스 변수를 사용하는 것입니다. (또한 소문자로 시작하는 대문자로 시작하는 메서드 이름을 지정하거나 사람들은 ShowNextname이 메서드 대신 클래스라고 생각할 수 있습니다.)

또한 [plistArray release];을 추가하는 것을 잊지 마십시오. 귀하의 dealloc 방법.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html

+0

감사합니다. - 지금 해당 문서를 읽으십시오. 예, 문제입니다. 매번 새로운 배열로 plist를 다시로드합니다. 당신이 말하는 것을 알고 있지만 그것을 구현하는 문법을 모른다면 - 아마도 plist를 뷰 컨트롤러의 인스턴스 변수에로드하는 코드 줄을 보여줄 수 있습니까? showNextName 내에서? 클래스/메서드에 대한 사용자 의견을 반영하여 내 코드 스타일을 변경하고 끝에 할당을 취소합니다. 당신의 도움을 주셔서 감사합니다. –

+0

.h에서 중괄호 사이에'plistArray'를 선언하십시오. 이렇게하면 클래스의'-' 메소드 중 하나에서 액세스 할 수있는 인스턴스 변수가됩니다. –

+0

프랭크 (Frank)가 말했듯이 인스턴스 변수를 free()가되지 않도록 설정하면 실제로 [plistArray retain]을 수행해야합니다. d. ('retain'과'release' 메쏘드는 count가 0이 될 때 free()가 호출되게하는 참조 카운트를 증가 시키거나 감소시킵니다, 그래서 당신은 카운트를 증가시키고 자하는 참조를가집니다.) 또한 http : /developer.apple.com/mac/library/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html 'retain'키워드를 사용하여 참조 카운트를 유지하는 데 도움이되는 속성을 선언하는 방법을 알려줍니다. – Nimrod

1

당신은 간접의 추가 레이어를 가지고 : 여기

은 당신이 어떤 도움이 될 읽어보십시오 좋은 무료 문서의

[NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(ShowNextName) userInfo:nil repeats:YES]; 

및 제거 : 당신은 다만 수 nameUpdate 메소드.

1

개체로의 전환에 대한 조언 - 구조체와 같은 개체에 대해 생각하는 것이 도움이됩니다. 메서드를 사용할 수도 있습니다. 인스턴스 변수는 구조체의 항목과 유사합니다. 정확한 구조체 (클래스 인스턴스)가 정확한 값을 얻기 위해 필요합니다. self는 메소드가 자체 클래스에서 보유한 값을 보는 방법 일뿐입니다. 따라서보기 컨트롤러의 메소드는 모두보기를 표시하기 위해 작성된보기 제어기 인 하나의 클래스 인스턴스를보고 있습니다.

또한 메모리를 생각하는 방법은 malloc과 같은 객체를 할당 할 때 - 어떤 맛의 초기화는 구조체에 초기 값을 설정하는 것과 같습니다 (malloced 메모리는 처음에는 아무것도 될 수 없으므로) . 그런 다음 그 릴리스 이후에 할당 된 메모리를 해제하는 것이지만 유지 호출이없는 경우에만 할당됩니다. 카운터와 함께 사용 된 메모리 블럭을 할당 한 마크를 유지하고 카운터를 감소 시키면 0이되면 메모리가 사라집니다. 이는 단순한보기이지만 시작하는 데 도움이 될 수 있습니다.

0

앱이 지속적으로 더 많은 메모리를 사용하는 경우 계측기 (누수 템플릿)에서 실행하고 모든 메모리가 어디로 이동하는지 확인합니다. 그런 다음 전체 크기가 커지는 클래스로 드릴 다운하고 할당 이벤트가 발생한 위치를 확인합니다. 그런 다음 the memory management rules을 (를) 위반하는 위치를 찾을 수 있습니다.

내가 보여준 코드에서 이러한 위반 사항을 볼 수 없으므로 문제는 다른 곳에 있어야합니다. 악기가 당신을 찾는데 도움이 될 것입니다.

This video 당신을 도울 수 있습니다.

+0

감사합니다. Peter 매우 도움이 되었어요. –