gpt4 book ai didi

c++ - EXC_BAD_ACCESS 从 NSTimer 调用 c++ 类方法

转载 作者:太空宇宙 更新时间:2023-11-04 11:22:41 25 4
gpt4 key购买 nike

在使用 Xcode4 构建 cocoa 应用程序时尝试混合使用 c++ 和 objective-c 时遇到问题。问题是当我使用 NSTimer 调用 handleFrame 函数时,它调用了一个类的虚函数。

这是我正在尝试做的:1.创建监视器;2.创建处理程序;3.将处理程序分配给监视器(初始化函数)4. 调用期望调用处理程序的虚方法的monitor->update()。5.代码在 applicationDidFinishLaunching 函数中按预期工作,但是 NSTimer 在 handleFrame 中导致 EXC_BAD_ACCESS 异常。

    //
// AppDelegate.h
// Concept5
//

#import <Cocoa/Cocoa.h>
#include "monitor.h"
#include "Derived.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
Monitor *monitor;`enter code here`
NSTimer *gameTimer;
}

@property (assign) IBOutlet NSWindow *window;

- (void)handleFrame:(NSTimer *)timer;

@end

AppDelegate implementation (.mm)

//
// AppDelegate.mm
// Concept5
//

#import "AppDelegate.h"

@implementation AppDelegate


- (void)dealloc
{
[super dealloc];
}

- (id) init {
self = [super init];
if(self) {
monitor = new Monitor();
}
return self;
}

- (void)handleFrame:(NSTimer *)timer {
monitor->update();
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
Derived derived;

monitor->init(derived);
monitor->update();

gameTimer = [[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(handleFrame:)
userInfo:nil
repeats:YES] retain];


monitor->update();

}
@end





//
// Monitor.cpp
// Concept5
//

#include "Monitor.h"


void Monitor::init (Base& handler)
{
_handler = &handler;
}

void Monitor::update()
{
if (_handler != NULL)
{
_handler->speak(); // <-- EXC_BAD_ACCESS exception.
}
}

//
// Monitor.h
// Concept5

#ifndef __Concept5__Monitor__
#define __Concept5__Monitor__

#include <iostream>
#include "Base.h"

class Monitor
{
private:
Base* _handler;
public:
void init (Base& handler);
void update();
};

#endif /* defined(__Concept5__Monitor__) */

//
// Base.cpp
// Concept5


#include "Base.h"

void Base::speak()
{
std::cout << "Base speaks" << std::endl;
}


//
// Base.h
// Concept5


#ifndef __Concept5__Base__
#define __Concept5__Base__

#include <iostream>

class Base
{
public:
virtual void speak();
};

#endif /* defined(__Concept5__Base__) */

//
// Derived.cpp
// Concept5


#include "Derived.h"

void Derived::speak()
{
std::cout << "Derived speaks" << std::endl;
}

//
// Derived.h
// Concept5
//

#ifndef __Concept5__Derived__
#define __Concept5__Derived__

#include <iostream>
#include "Base.h"

class Derived : public Base
{
public:
void speak();
};
#endif /* defined(__Concept5__Derived__) */

最佳答案

我从未使用过 Objective-C,但以下看起来像是一个问题:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
Derived derived;
monitor->init(derived);
//....
}

由于Derived是局部变量,作用域不会超出applicationDidFinishLaunching函数。因此,当上述函数返回时,调用 init()(它接受一个指针)将持有一个无效对象。

如果这是 C++,解决方案是确保对象的生命周期足够长。通常的解决方案是:

1) 使对象成为全局对象,或者

2) 使用new动态创建对象,或者

3) 创建一个智能指针(可能是 std::shared_ptr)并使用它代替原始指针。

关于c++ - EXC_BAD_ACCESS 从 NSTimer 调用 c++ 类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27738706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com