NSStringto类成员分配崩溃

问题描述 投票:1回答: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;

它的init方法:

- (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。我已阅读,似乎崩溃可能是由于额外的释放或腐败。

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

在此先感谢和问候

properties crash nsstring objective-c++ manual-retain-release
1个回答
0
投票

有几件事让我觉得你给的代码很奇怪:

Bridge-casting in MRC Code

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

通常,您在将ObjC指针指定给void*的位置进行桥接转换,或者当您想将void*移回ObjC指针时(即所有形式的桥接转换表示从手动处理到允许ARC执行此操作的更改)背部)。

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

Releasing Objects through their Accessors

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

[_data1 release];

要么

[self->_data1 release];

或指定NIL并让访问者进行释放

self.data1 = nil;

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

© www.soinside.com 2019 - 2024. All rights reserved.