Отображение случайных слов из словаря Plist - утечка памяти? - PullRequest
0 голосов
/ 16 января 2010

Я новичок в разработке для iPhone. Я "старая школа" - меня научили использовать процедуры и т. Д. При программировании. В наши дни все ориентировано на объекты, но мой стиль остается таким же, каким был всегда. Пожалуйста, имейте это в виду. Мой проект крошечный и просто доказательство концепции.

Программа ниже работает по таймеру - каждые 30 секунд она будет читать случайное имя ребенка из моей базы данных списков имен, сохраненной в Dictionary.plist моим приложением. Затем он показывает это имя на экране iphone.

Вы можете увидеть соответствующие части кода ниже. Что происходит - если я увеличу таймер, чтобы запустить его очень быстро - в конце концов, кажется, что ему не хватает памяти или что-то еще, как он показывает ???? вместо следующего случайного имени ребенка. Я подозреваю, что это связано с тем, что я не закрываю файл базы данных каждый раз, когда читаю его.

В любом случае, может кто-нибудь, пожалуйста, посмотрите на мой код (с учетом моих вышеупомянутых комментариев) и скажите мне, что мне нужно добавить, чтобы он не показывался ???? после стольких пробежек ..

Я открываю файл каждый раз только в 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];
}

Ответы [ 4 ]

1 голос
/ 16 января 2010

У вас есть дополнительный слой косвенности: вы можете просто сделать:

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

и исключите метод nameUpdate.

1 голос
/ 16 января 2010

Советы по переходу к объектам - это помогает думать об объектах, подобных структурам, о которых вы также можете иметь методы. Переменные экземпляра похожи на элементы в структуре, где вам нужна конкретная структура (экземпляр класса), чтобы получить точное правильное значение - self - это просто способ для метода посмотреть на значение, хранящееся в его собственном классе. Таким образом, все методы в контроллере представления смотрят на один экземпляр класса, контроллер представления, который был создан для отображения вашего представления.

Кроме того, способ думать о памяти заключается в том, что когда вы выделяете объект, который действительно похож на malloc, init любого аромата подобен установке начальных значений в структуре (поскольку изначально размещенная в памяти память может быть чем угодно). Затем после этого выпуска освобождается выделенная память, но ТОЛЬКО если не было никаких вызовов сохранения. Сохраните отметки, которые распределяют блок памяти как используемый со счетчиком, и освобождайте счетчики, уменьшающие счетчик - когда он обращается в 0, память исчезает. Это упрощенное представление, но может помочь вам начать.

1 голос
/ 16 января 2010

Проблема может заключаться в том, что каждые 30 секунд вы перезагружаете plist в новый массив. Что вы должны сделать - это загрузить view plid в переменную экземпляра объекта (класс контроллера вашего представления), а затем просто использовать эту переменную экземпляра в showNextName. (Кроме того, я бы всегда называл методы, начинающиеся со строчной буквы, а классы - заглавной, иначе люди могут подумать, что ShowNextname - это класс, а не метод.)

Также не забудьте добавить [plistArray release]; в ваш метод dealloc.

Вот хороший бесплатный документ, который вы, возможно, захотите прочесть, который может помочь некоторым:

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

0 голосов
/ 16 января 2010

Если ваше приложение постоянно использует больше памяти, запустите его в разделе «Инструменты» (шаблон «Утечки») и посмотрите, куда уходит вся эта память. Затем перейдите к классу, общий размер которого растет, и посмотрите, где происходят события выделения. Тогда вы сможете найти, где вы нарушаете правила управления памятью .

Я не вижу подобных нарушений в коде, который вы показали, поэтому проблема должна быть в другом месте. Инструменты помогут вам найти его.

Это видео может вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...