NSTimer сбой моего приложения - PullRequest
1 голос
/ 11 мая 2011

Итак, у меня есть приложение, которое использует NSTimer. Проблема в том, что при запуске NSTimer мое приложение вылетает с EXC_BAD_ACCESS. Я только начал с target-c, поэтому не знаю, как правильно его отладить. Если я подумаю, позвоните -(void)logIn{} с [self logIn];, приложение будет работать. Мой код:
.h

@interface DJ_WAppDelegate : NSObject {
   NSTimer *loginTimer;
    }

    -(void)logIn;  

    @end

.m

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [self logIn];   // this works
    loginTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(logIn) userInfo:nil repeats:YES];   // this fails
}

- (void)logIn {
    NSLog(@"Logging in...");

    // if I comment out these 2 lines it works with the NSTimer!?... (I've would have more code below)
    NSURL *loginConn = [NSURL URLWithString:[NSString stringWithFormat:@"some-website.com"]];   
    NSInteger loginReturn = [[NSString stringWithContentsOfURL:loginConn encoding:NSASCIIStringEncoding error:nil] intValue];

   // when "loginReturn" return "OK" the timer (loginTimer) will be stopped with: [loginTimer invalidate];

   // more code would be below... (which works!)
}


Так что проблема в NSURL, он думает. Спасибо за помощь.

РЕДАКТИРОВАТЬ 1: Вот аварийный стек:

    EException Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000020
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
objc_msgSend() selector name: respondsToSelector:


Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x9603bed7 objc_msgSend + 23
1   com.apple.CoreFoundation        0x922ed5f2 _CFStringAppendFormatAndArgumentsAux + 3138
2   com.apple.CoreFoundation        0x922ec979 _CFStringCreateWithFormatAndArgumentsAux + 105
3   com.apple.Foundation            0x9656ebfb -[NSPlaceholderString initWithFormat:locale:arguments:] + 163
4   com.apple.Foundation            0x9656eaae +[NSString stringWithFormat:] + 88
5   com.who.DJ-W                0x00001d56 -[DJ_WAppDelegate logIn] + 116 (DJ_WAppDelegate.m:108)
6   com.apple.Foundation            0x965b08d4 __NSFireTimer + 141
7   com.apple.CoreFoundation        0x922ffadb __CFRunLoopRun + 8059
8   com.apple.CoreFoundation        0x922fd464 CFRunLoopRunSpecific + 452
9   com.apple.CoreFoundation        0x922fd291 CFRunLoopRunInMode + 97
10  com.apple.HIToolbox             0x91646e04 RunCurrentEventLoopInMode + 392
11  com.apple.HIToolbox             0x91646bb9 ReceiveNextEventCommon + 354
12  com.apple.HIToolbox             0x91646a3e BlockUntilNextEventMatchingListInMode + 81
13  com.apple.AppKit                0x9265378d _DPSNextEvent + 847
14  com.apple.AppKit                0x92652fce -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156
15  com.apple.AppKit                0x92615247 -[NSApplication run] + 821
16  com.apple.AppKit                0x9260d2d9 NSApplicationMain + 574
17  com.who.DJ-W                0x00001c92 start + 54

надеюсь, это поможет ... найти ошибку

РЕДАКТИРОВАТЬ 2:
При включенном режиме зомби я получаю следующее: *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x46d550 Надеюсь, это поможет.

РЕДАКТИРОВАТЬ 3:
To Ball : Вот исходный URL (забрал домен здесь) /DJW/work.php?user=iBlackbirdi&udid=00000000-0000-1000-80005&key=660e5744e&cmd=slocau&type=get

Ответы [ 2 ]

3 голосов
/ 11 мая 2011

Здесь есть несколько проблем:

  1. djwLog - это метод класса, поэтому вы должны вызывать его для класса, а не для экземпляра, подобного этому: [[self class] djwLog:@"foo bar"]

  2. В методе URLFromString: требуется, чтобы строка содержала действительный URL-адрес, указанный в RFC 1808 .Нечто в духе [NSURL URLFromString:@"http://example.com/foo"]

  3. stringWithContentsOfURL:url… является синхронным методом.Если этот код не запущен в отдельном потоке, вы не должны его использовать.Посмотрите на NSURLConnection класс для асинхронной загрузки данных из URL.Использование синхронизированных вызовов для этого является плохой идеей.Всегда.

  4. intValue возвращает signed integer.Чтобы получить NSInteger, используйте integerValue.Также, если вы используете stringWithContentsOfURL, убедитесь, что перед вызовом integerValue проверьте, равен ли он nil, в противном случае вы можете получить результат 0, если вызов URL не удался или не вернул данные.Реальный парсер для API, который вы вызываете, был бы хорошей идеей в любом случае.

2 голосов
/ 11 мая 2011

Вы вызываете метод класса, как если бы он был методом экземпляра:

[self djwLog:@"Logging in..."];

Поскольку не существует метода экземпляра с именем djwLog, приложение аварийно завершает работу. Вы должны либо вызвать NSLog напрямую, сделать его методом экземпляра - или, предпочтительно, создать макрос для ведения журнала:

#ifdef DEBUG
#   define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
#   define DLog(...) do { } while (0)
#endif

Если вы вместо NSLog напишите DLog - он будет регистрироваться только тогда, когда определен флаг DEBUG. В дополнение к этому, он будет регистрировать источник сообщения журнала, чтобы вы могли видеть, из какого класса / метода поступила запись журнала.

...