【问题标题】:NSStringto class member assignation crashesNSStringto 类成员分配崩溃
【发布时间】:2019-03-20 09:56:27
【问题描述】:

我正在开发 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。我已阅读,似乎崩溃可能是由于额外的释放或损坏。

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

提前致谢和问候

【问题讨论】:

  • 我不相信您的问题出在您发布的代码中。您是否尝试过在启用 Zombie 对象诊断的情况下运行您的代码?我怀疑您在其他地方遇到了引用问题。我不太喜欢你的代码的一件事是[self.data1 release];。这不一定总是错误的,但如果 self.data1 再次被 [super dealloc] 间接使用,它可能会导致问题。考虑改用self.data1 = nil;,这不会留下任何悬空引用。

标签: properties crash nsstring objective-c++ manual-retain-release


【解决方案1】:

你给出的代码有几处让我觉得很奇怪:

MRC 代码中的桥接

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

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

在释放支持 ObjC 属性之前,不需要桥接转换支持 ObjC 属性的 ObjC 指针。

通过访问器释放对象

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

[_data1 release];

[self->_data1 release];

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

self.data1 = nil;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2021-12-31
    • 2017-03-22
    相关资源
    最近更新 更多