2013-03-18 3 views
1

Я пишу программу для синтаксического анализа XML. Процесс синтаксического анализа работает хорошо, но мне нужно повторить функцию через каждые 25 секунд. Я пробовал NSTimer, но он не работает для меня. Когда он вызывается, он показывает ошибку SIGABRT. Функция, которая мне нужно вызвать через каждые 25 секунд, приводится ниже:Как реализовать NSTimer в параметризованной функции?

-(id)loadXMLByURL:(NSString *)filePath :(NSTimer *) timer 
{ 
    categories =[[NSMutableArray alloc]init]; 
    NSData *myData = [NSData dataWithContentsOfFile:filePath]; 
    parser =[[NSXMLParser alloc]initWithData:myData]; 
    parser.delegate = self; 
    [parser parse]; 
    return self; 
} 

И метод, который я использовал для установки таймера приведена ниже

- (void)viewDidLoad 
{ 
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cd_catalog" ofType:@"xml"]; 


    NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval: 25.0 target: self 
                 selector: @selector(loadXMLByURL:filePath:) userInfo: nil repeats: YES]; 

    xmlParser=[[XMLParser alloc] loadXMLByURL:filePath:myTimer]; 
    [super viewDidLoad]; 
} 

Пожалуйста, скажите мне, что случилось с моим код, а также скажите, есть ли какой-либо другой метод, доступный для процесса с примером.

Заранее спасибо.

+0

Почему у вас есть 'return self?' В вашем методе? – tolgamorf

+0

Почему вы хотите разобрать один и тот же файл каждые 25 секунд? Почему бы не разобрать его один раз и сохранить данные? – rmaddy

+0

@rmaddy Я считаю, что файл XML будет предоставлен из удаленного источника, и он будет слушать изменения в файле или что-то подобное. – tolgamorf

ответ

2

Селектор, который вы используете для таймера, может принимать только один параметр, и это будет таймер. Вы не можете передать filePath в селектор таймера.

Удалить параметр filePath и сделать путь переменной экземпляра.

-(id)loadXML { 
    categories =[[NSMutableArray alloc]init]; 
    NSData *myData = [NSData dataWithContentsOfFile:filePath]; // filePath is an ivar 
    parser =[[NSXMLParser alloc]initWithData:myData]; 
    parser.delegate = self; 
    [parser parse]; 
    return self; 
} 

- (void)viewDidLoad { 
    // filePath is now an ivar 
    filePath = [[NSBundle mainBundle] pathForResource:@"cd_catalog" ofType:@"xml"]; 

    // The timer isn't needed by the selector so don't pass it 
    NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval:25.0 target:self 
           selector:@selector(loadXML) userInfo:nil repeats:YES]; 

    xmlParser=[[XMLParser alloc] loadXML]; 
    [super viewDidLoad]; 
} 

Примечание: вы должны указать каждый параметр. Ваш оригинальный метод был назван loadXMLByURL::. Обратите внимание на два двоеточия, между которыми нет ничего.

+0

Я думаю, что это правильный ответ. Просто любопытно, есть ли особая причина, по которой метод 'loadXML' возвращает' self'? Не может ли быть просто '(void) loadXML'? – tolgamorf

+0

Это может быть недействительным. Я верю, что он только что вернулся, потому что именно так вы сделали это в своем коде. – Jsdodgers

+0

@ Jsdodgers благодарит за разъяснения. Между прочим, это был не я. – tolgamorf

0

Я считаю, что ваша проблема в том, что вы передаете ему селектор @selector (loadXMLByURL: filePath :), который имеет два параметра, но селектор NSTimer должен иметь только один параметр, который является самим таймером.

Из документов на NSTimer:

aSelector The message to send to target when the timer fires. The selector must correspond to a method that returns void and takes a single argument. The timer passes itself as the argument to this method.

Вам нужно создать метод, который имеет лишь NSTimer * (или идентификатор) в качестве параметра и получить имя файла из других источников.

Редактировать: Вот ссылка на ссылку на класс для NSTimer.