1

Possible Duplicate:
NSTimer doesn't stop

I am having a hard time stopping my timer, witch pings to my server. I already searched for other answers here and on other places, but i can`t seem to find where i have gone wrong.

I decided to make an example code with the same idea, but, you click a button the timer starts, you click another the timer ends, and it worked the way it should. Please don't mind if i did something wrong (other than the timer part) i'm new in this. All i want to know is why won`t it stop..

Thanks in advance.

Connection.h

#import <Foundation/Foundation.h>


@interface Connection : NSObject 
{  
NSString *urlString;
NSURL *url;
NSMutableURLRequest *request;
NSURLConnection *connection;
NSURLResponse *response;
NSMutableData *receivedData;
NSData *responseData;
NSError *error;

NSTimer *timer;
}
@property (nonatomic, retain) NSTimer *timer;

-(BOOL)authenticateUser:(NSString *)userName Password:(NSString *)password;
-(BOOL)checkConnection;
-(void)ping:(NSTimer *)aTimer;
-(void)logout;
-(void)timerStart;
-(void)timerStop;

@end

Connection.m

#import "Connection.h"
#import "Parser.h"
#import "Reachability.h"
#import "TBXML.h"

@implementation Connection

@synthesize timer;

-(BOOL) authenticateUser:(NSString *)userName Password:(NSString *)password
{
BOOL success;
urlString = [[NSString alloc] initWithFormat:@"my/server/address/login"];
url =[[NSURL alloc] initWithString:urlString];
request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
error = [[NSError alloc] init];
responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[responseData retain];
NSString *tempString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSMutableDictionary *tempDict= [[NSMutableDictionary alloc] init];
if (request)
{
    Parser *parser = [[Parser alloc] init];
    tempDict = [parser readXMLString:tempString];
    for (id key in tempDict)
    {
        NSLog(@"%@ is %@",key,[tempDict objectForKey:key]);
    }
    if ([[tempDict objectForKey:@"login"] isEqualToString:@"true"] )
    {
        success = YES;
            self.timerStart;
    }
    else
    {
        success = NO;
    }
}
[urlString release];
[url release];
[error release];
[responseData release];
[tempString release];
return success;
}

-(void)logout
{
    self.timerStop;
}

-(void)ping:(NSTimer *)aTimer;
{
urlString = [[NSString alloc] initWithFormat:@"my/server/address"];
url =[[NSURL alloc] initWithString:urlString];
request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];

NSLog(@"ping");

[urlString release];
[url release];
}

-(BOOL)checkConnection
{
Reachability *reachability = [Reachability reachabilityWithHostName:@"http://my/server/address"];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];

if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
    return NO;
}
else
{
    return YES;
}
}

-(void)timerStart
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(ping:) userInfo:nil repeats:YES];
}
-(void)timerStop
{
[self.timer invalidate];
self.timer = nil;
}


@end
Community
  • 1
  • 1
Erakk
  • 922
  • 5
  • 13

3 Answers3

2

In timerStart you just replace whatever is in the timer property. If you start a second timer without stopping the first one, it will run forever. So timerStart should first call timerStop before creating a new one (and should probably have a new name then as it would be silly to call timerStop from timerStart).

w-m
  • 10,772
  • 1
  • 42
  • 49
  • But i`m not creating a new one, at least from what i understand. When the user logs in, the authenticate method starts the timer. When the user leaves the screen/logs off, the method viewDidUnload will call logout wich will call timerStop, terminating the last (and the only) timer i created, am i right? Unless you`re saying that by setting the self.timer properties i am actually creating a new one? – Erakk Aug 24 '11 at 21:11
  • Ok, i found the culprit: In my RootViewController, i was instantiating my Connection to log in, but at the same thread i was releasing it. This thread created the timer. But, when i left the view, i needed to destroy the timer, so i created yet another Connection instance, just to logout, releasing it right after that. So your advice applied here well, since i was creating a time but destroying another that did not existed. – Erakk Aug 24 '11 at 21:48
0

Use [self timerStop]; using dot syntax is ONLY for properties (and will generate a warning if you don't), not calling a method in the way you're doing it.

Edit: This won't fix your problem, but doing it the way you are is very bad coding practice

Matt S.
  • 13,305
  • 15
  • 73
  • 129
  • Maybe you should clarify that changing that won't make a difference. It might be bad coding practice, but the result will be exactly the same. – w-m Aug 23 '11 at 01:56
  • Thanks, i am learning objective C as i write this so any constructive criticism is appreciated. – Erakk Aug 24 '11 at 20:56
0
-(void)timerStart
{
    [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(ping:) userInfo:nil repeats:YES];
}
AWF4vk
  • 5,810
  • 3
  • 37
  • 70