Попытка использовать NSTimer - PullRequest
       21

Попытка использовать NSTimer

0 голосов
/ 06 октября 2011

У меня проблема с тем, чтобы заставить работать NSTimer, возможно, потому, что я не знаю, как правильно его использовать (я пытался прочитать документацию по Apple, она мне не сильно помогла).Я получаю время от UIDatePicker и хочу, чтобы приложение вызывало метод, когда это время достигнуто.Просто нет?Вот код, который у меня есть:

-(IBAction)SetButtonPress:(id)sender{
     NSDate *date = [Picker date];
     alarmTimer = [[AlarmTimer alloc] init];
    [alarmTimer runTimer: Picker.date];
}

Несколько вещей теперь соответствуют стандартам, но они все еще не работают.Он все еще дает мне время на 6 часов вперед, и когда он достигает этого времени, он ничего не делает.

И код метода RunTimer моего класса alarmTimer выглядит следующим образом:

-(void)RunTimer: (NSDate *) date
{
NSRunLoop *theLoop = [NSRunLoop currentLoop];
[theLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[timer initWithFireDate:date interval:0 target:self selector:@selector(Play) userInfo: nil repeats:NO];
}

Несколько вещей теперь следуют стандартам, но они все еще не работают.Он все еще дает мне время на 6 часов вперед, и когда он достигает этого времени, он ничего не делает.

И на всякий случай это помогает, вот файлы .h и .m для контроллера представления: .h:

//
//  Assignment_1ViewController.h
//  Assignment 1
//
//  Created by Jack Schaible on 11-09-28.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AlarmTimer.h"

@interface Assignment_1ViewController : UIViewController {
    UIButton *SetButton;
    UIDatePicker *Picker;
    UIButton *CancelButton;
    NSString *time;
    AlarmTimer *alarmTimer;
}

@property (nonatomic, retain) IBOutlet UIButton *SetButton;
@property (nonatomic, retain) IBOutlet UIDatePicker *Picker;
@property (nonatomic, retain) IBOutlet UIButton *CancelButton;

- (IBAction)SetButtonPress:(id)sender;
- (IBAction)CancelButtonPress:(id)sender;
@end

.m:

//
//  Assignment_1ViewController.m
//  Assignment 1
//
//  Created by Jack Schaible on 11-09-28.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Assignment_1ViewController.h"
#import "AlarmTimer.h"

@implementation Assignment_1ViewController
@synthesize Picker;
@synthesize CancelButton;
@synthesize SetButton;

- (void)dealloc
{
    [SetButton release];
    [Picker release];
    [CancelButton release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle


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


- (void)viewDidUnload
{
    [self setSetButton:nil];
    [self setPicker:nil];
    [self setCancelButton:nil];
    [super viewDidUnload];
    [alarmTimer release];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (IBAction)SetButtonPress:(id)sender {
    NSDateFormatter *ndf = [[NSDateFormatter alloc] init];

    time = [ndf stringFromDate:self.Picker.date];

    alarmTimer = [AlarmTimer alloc];
    [alarmTimer init];

    NSLog(@"Date is: %@", [ndf dateFromString:time]);

    [alarmTimer RunTimer:[ndf dateFromString:time]];
}

- (IBAction)CancelButtonPress:(id)sender {
}
@end

И код для класса AlarmTimer:

.h:
//
//  Timer.h
//  Assignment 1
//
//  Created by Jack Schaible on 11-09-28.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface AlarmTimer : NSObject {
    NSString *time;
    NSTimer *timer;
    AVAudioPlayer *player;
}

-(void) RunTimer: (NSDate *)date;
-(void)Play;
-(void)CancelTimer;

@end

И, наконец, .m:

//
//  Timer.m
//  Assignment 1
//
//  Created by Jack Schaible on 11-09-28.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "AlarmTimer.h"
@implementation AlarmTimer

-(id) init
{
    if(self == [super init])
    {
        timer = [NSTimer alloc];
        NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/Time.mp3", [[NSBundle mainBundle] resourcePath]]];
        NSError *error;
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    }
    return self;
}

- (void) RunTimer: (NSDate *)date
{
    [timer initWithFireDate:date interval:86400 target:self selector:@selector(Play) userInfo:nil repeats:NO];
    NSLog(@"Date is: %@", date);
}

-(void) Play
{
    [player play];
    UIAlertView *aView = [[UIAlertView alloc] initWithTitle:@"Holy Chimes!" message:@"If you didn't hear that..." delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil, nil];
    [aView show];
}

-(void)CancelTimer
{
    time = nil;
}

@end

Большое спасибо всем, кто может помочь!

Ответы [ 2 ]

1 голос
/ 06 октября 2011

Почему вы используете NSDateFormatter? попробуйте сделать это так:

alarmTimer = [AlarmTimer alloc];
[alarmTimer init];

NSLog(@"Date is: %@", self.Picker.date);

[alarmTimer RunTimer: self.Picker.date];
0 голосов
/ 06 октября 2011
  1. Как правило, делайте + alloc и -init вместе: Foo *someFoo = [[Foo alloc] init];. Не разделяйте вызовы, как вы делали с переменными timer и alarmTimer. Причина этого заключается в том, что иногда инициализатор возвращает другой указатель, чем тот, который вы получаете от +alloc, и когда это происходит, вы хотите быть уверены, что сохраните этот новый указатель. Я не знаю, если NSTimer когда-либо делает это, но если это так, у вас будут все виды проблем с текущим кодом.

  2. Не пытайтесь повторно использовать таймер. Как только он сработает, отпустите его и создайте новый, когда вам нужно.

  3. Что за сумасшествие в -SetButtonPress:? Вы получаете дату из средства выбора даты, конвертируете ее в строку, а затем немедленно конвертируете эту строку обратно в дату ... почему?

  4. Вы используете интервал в 24 часа (86400 секунд) для своего таймера. У вас ошибочное впечатление, что таймер с большим интервалом разбудит приложение, которое находится в фоновом режиме? NSTimer опирается на цикл выполнения; когда цикл выполнения не работает, таймер не работает.

  5. Было бы несколько легче помочь вам, если бы вы придерживались обычного соглашения Objective C и методов имен, начинающихся с символов нижнего регистра, то есть -runTimer: вместо -RunTimer:. То же правило применяется к переменным экземпляра.

...