2011-05-11 117 views
0

所以我有一个应用程序使用NSTimer。问题是,当NSTimer运行时,我的应用程序将崩溃EXC_BAD_ACCESS。我只是开始使用objective-c,所以我不知道如何正确调试它。如果我认为请拨打-(void)logIn{}[self logIn];,该应用程序将起作用。 我的代码:
.HNSTimer崩溃我的应用程序

@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:
Ball:这里是原来的URL(带走这里的域)/DJW/work.php?user=iBlackbirdi&udid=00000000-0000-1000-80005&key=660e5744e&cmd=slocau&type=get

+1

如果您发布崩溃堆栈,找出崩溃的情况会更容易。 – smorgan

+0

定时器何时应该停止射击?请为您的活动可执行文件[请启用NSZombie](http://cocoa-nut.de/?p=16)并查看控制台输出是否产生新的内容。 –

+0

我不知道如果你的原始字符串的URL包括一些网址编码%escapes这会混淆stringWithFormat – kball

回答

3

这里有几个问题:

  1. djwLog是一个类的方法,所以你应该把它的类而不是实例 这样的:

  2. URLFromString:方法需要字符串包含由RFC 1808指定的有效URL。沿线的东西[NSURL URLFromString:@"http://example.com/foo"]

  3. stringWithContentsOfURL:url…是一种同步方法。除非你有这个代码运行在一个单独的线程中,否则不应该使用它。查看NSURLConnection以便从一个URL异步加载数据。对此使用同步调用是一个不好的想法。总是。

  4. intValue返回signed integer。要获得NSInteger,请使用integerValue。此外,如果您使用stringWithContentsOfURL,请确保在致电 integerValue之前检查结果是否为nil,否则如果URL调用失败或未返回数据,则可能得到0的结果。在任何情况下,您所调用的API的真正解析器都是一个好主意。

+0

很多东西我不知道...谢谢你的回复。它的目的是,如果URL调用失败,结果为0!因为服务器只会返回数字......无论如何,这解决了我的问题。 – Silicone

2

你调用一个类的方法,如果它是一个实例方法:

[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标志已经定义它只会被记录。除此之外,它还会记录日志消息的来源 - 因此您可以看到日志条目来自哪个类/方法。

+0

感谢您的答复。我知道我可以直接用'NSLog()'来完成。在我写这篇文章后,我注意到我发布的代码并不像我这样做。 '[self djwLog @“”]'确实有效。我将在我的问题中用'NSLog()'替换我的方法。 – Silicone