NSTimer 使我的应用程序崩溃

发布于 2024-11-06 14:33:36 字数 3506 浏览 3 评论 0原文

所以我有一个使用 NSTimer 的应用程序。问题是,当 NSTimer 运行时,我的应用程序将崩溃并显示 EXC_BAD_ACCESS。我刚刚开始使用 Objective-C 所以我不知道如何正确调试它。如果我认为使用 [self logIn]; 调用 -(void)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:
Ball:这是原始 URL(此处去掉了域名)/DJW/work.php?user =iBlackbirdi&udid=00000000-0000-1000-80005&key=660e5744e&cmd=slocau&type=get

So I have an application which uses an NSTimer. The problem is that when the NSTimer runs, my application will crash with EXC_BAD_ACCESS. I only just started with objective-c so I don't know how to properly debug it. If I thought call the -(void)logIn{} with [self logIn]; the application will work.
My code:
.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!)
}

So the problem is with the NSURL it think.
Thanks for helping.

EDIT 1:
Here's the crash stack:

    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

hope this helps... to find the error

EDIT 2:
With the Zombie Mode on I get this: *** -[CFString respondsToSelector:]: message sent to deallocated instance 0x46d550 I hope this helps.

EDIT 3:
To Ball: Here is the original URL (took away the domain here) /DJW/work.php?user=iBlackbirdi&udid=00000000-0000-1000-80005&key=660e5744e&cmd=slocau&type=get

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岛徒 2024-11-13 14:33:37

这里有几个问题:

  1. djwLog 是一个类方法,因此您应该在类而不是实例上调用它
    像这样: [[self class] djwLog:@"foo bar"]

  2. URLFromString: 方法需要字符串包含 RFC 1808。类似于 [NSURL URLFromString:@"http://example.com/foo"]

  3. stringWithContentsOfURL:url… 是一种同步方法。除非您将此代码运行在单独的线程中,否则不应使用它。查看 NSURLConnection 中的一个类,用于从 URL 异步加载数据。为此使用同步调用是一个主意。总是。

  4. intValue 返回一个有符号整数。要获取 NSInteger,请使用 integerValue。另外,如果您使用 stringWithContentsOfURL,请确保在调用之前检查其结果是否为 nil
    integerValue 否则,如果 URL 调用失败或未返回数据,您可能会得到 0 结果。无论如何,为您调用的 API 提供一个真正的解析器都是一个好主意。

There are several problems here:

  1. djwLog is a class method so you should call it on the class not the instance
    like this: [[self class] djwLog:@"foo bar"]

  2. The URLFromString: method needs the string to contain a valid URL as specified by RFC 1808. Something along the lines of [NSURL URLFromString:@"http://example.com/foo"]

  3. stringWithContentsOfURL:url… is a syncornous method. Unless you have this code running in a separate thread you should not use this. Look at NSURLConnection for a class to asynchronously load data from a URL. Using synchronized calls for this is a bad idea. Always.

  4. intValue returns a signed integer. To get a NSInteger use integerValue. Also if you use stringWithContentsOfURL make sure to check if it's result is nil before calling
    integerValue otherwise you might get a result of 0 if the URL call failed or did not return data. A real parser for the API you are calling would be a good idea in any case.

我要还你自由 2024-11-13 14:33:37

您调用类方法就好像它是实例方法一样:

[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-flag 时进行日志记录。除此之外,它还会记录日志消息的来源 - 这样您就可以看到日志条目来自哪个类/方法。

You're calling a class method as if it was an instance method:

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

Since there is no instance-method named djwLog the application crashes. You should either call NSLog directly, make it an instance-method - or preferably make a macro for logging:

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

If you instead of NSLog write DLog - it will only be logging when DEBUG-flag has been defined. In addition to this, it will log the origin of the log message - so you can see which class/method the log entry came from.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文