1

我正在开发 C++ 和 Objective-C++ 应用程序。我有 C++ 类,它调用 Objective-c++ 类。在 c++ 标头中,我正在创建 void* ,如下所示:

void *m_self;

然后在构造函数中我像这样实例化objective-c++:

m_self = [[InfoForMac alloc] init];

在析构函数中我这样做:

[(__bridge id)m_self release];

Objective-C++ 类有这个接口:

@interface InfoForMac : NSObject  
@property (nonatomic, copy) NSString* data1;
@property (nonatomic, copy) NSString* data2;
@property (nonatomic, assign) int val;

它的初始化方法:

- (id) init
{
 if ( (self = [super init]) ) {
    self.data1 = @"";
    self.data2 = @"";
    self.val = -1;
 }
 return self;
}

及其析构函数:

-(void)dealloc
{
 [self.data1 release];
 [self.data2 release];
 [super dealloc];
}

我从 C++ 调用 Objective-C++ 方法,如下所示:

 [(__bridge id)m_self getData1];
 QString dataFromMac = QString::from NSString([(__bridge id)m_self data1]);

相关方法如下:

- (void) getData1
{
  NSRunningApplication* activeApp = nil;
  activeApp = [[NSWorkspace sharedWorkspace] frontmostApplication];
  if (activeApp) {
    NSString* activeAppLocalizedName = [activeApp localizedName];
    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
    if (windowList) {
        NSArray *windows = (__bridge NSArray*)(windowList);
        for (NSDictionary *window in windows) {
            NSString* owner = [window objectForKey:@"kCGWindowOwnerName"];
            if (activeAppLocalizedName != nil &&
                [owner isEqualToString:activeAppLocalizedName]) {
                self.data1 = activeAppLocalizedName;
            }
        }
        CFRelease(windowList);
    }
  }
}

C++ 类被销毁并重新创建。问题是,在我重新创建类并调用 getData1 方法时销毁类后,我在这里遇到了崩溃:

self.data1 = activeAppLocalizedName;

使用调试器堆栈跟踪检查显示该调用,然后显示 objc_msgSend。我已阅读,似乎崩溃可能是由于额外的释放或损坏。

有人可以帮我理解发生了什么吗?

提前致谢和问候

4

1 回答 1

0

关于您提供的代码,有几件事让我感到奇怪:

MRC 代码中的桥接

为什么要在发布前进行桥接?您应该是桥接(使用 ARC)或释放。但你似乎两者都做。可能是您实际上并没有在代码中关闭 ARC,而现在正在释放 ARC 仍然认为它拥有的对象?

通常,您在将 ObjC 指针分配给 a 的点进行桥接转换void*,或者当您想将 avoid*移回 ObjC 指针时(即所有形式的桥接转换表示从手动处理到让 ARC 执行和返回的更改) .

在释放它之前桥接支持 ObjC 属性的 ObjC 指针应该是不必要的。

通过访问器释放对象

我不认为这是你的大问题(它应该在功能上等效),但它仍然看起来很奇怪:通常,要么释放实例变量

[_data1 release];

或者

[self->_data1 release];

或分配 NIL 并让访问者进行释放

self.data1 = nil;

您正在向访问者请求一个对象,然后释放它。应该没问题(应该是同一个对象),但是很奇怪,访问器通常会将其对象添加到当前的自动释放池中,因此您的对象可能会比您想象的更晚释放。

于 2019-03-31T13:31:08.777 回答