使用标志`-fobjc-arc`时的分段错误

时间:2017-06-21 14:38:48

标签: objective-c macos bluetooth automatic-ref-counting iobluetooth

我在Mac OSX上使用IOBluetooth框架进行设备发现。我在回调函数中添加了一些NSLog(),所以我知道了进度。

如果我使用 gcc on command line 编译代码,那么一切正常(源文件f.m,输出a):

gcc -o a f.m -framework Foundation -framework IOBluetooth

但是,如果我添加-fobjc-arc标志以确保自动引用计数:

gcc -fobjc-arc -o a f.m -framework Foundation -framework IOBluetooth

编译仍然可以,但执行文件./a会导致seg错误:

2017-06-21 22:06:23.150 a[718:17437] Program started ...
Segmentation fault: 11

或永远挂在那里:

2017-06-21 22:06:27.070 a[721:17809] Program started ...

有时它会挂起,有时会出现故障。行为不一致。如果我没有添加-fobjc-arc标记,那么一切都按预期工作(至少在表面上)。

所以我的问题是,为什么它在添加-fobjc-arc标志后的行为方式?

如果有帮助,完整的源文件就在这里:

#import <IOBluetooth/IOBluetooth.h>

@interface InquiryDelegate : NSObject <IOBluetoothDeviceInquiryDelegate>
@end

@implementation InquiryDelegate
-(void)deviceInquiryStarted:(IOBluetoothDeviceInquiry *)sender
{
    NSLog(@"Inquiry started ...");
}

-(void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry *)sender
                         device:(IOBluetoothDevice *)device
{
    NSLog(@"Device found");
}

-(void)deviceInquiryComplete:(IOBluetoothDeviceInquiry *)sender
                       error:(IOReturn)error
                     aborted:(BOOL)aborted
{
    NSLog(@"Inquiry complete");
}

-(void)deviceInquiryUpdatingDeviceNamesStarted:(IOBluetoothDeviceInquiry *)sender
                              devicesRemaining:(uint32_t)devicesRemaining
{
}

-(void)deviceInquiryDeviceNameUpdated:(IOBluetoothDeviceInquiry *)sender
                               device:(IOBluetoothDevice *)device
                     devicesRemaining:(uint32_t)devicesRemaining
{
}
@end

int main(int argc, const char* argv[]) {
    @autoreleasepool {
        NSLog(@"Program started ...");

        IOBluetoothDeviceInquiry* di = [[IOBluetoothDeviceInquiry alloc]
                                           initWithDelegate:[[InquiryDelegate alloc] init]];
        [di start];

        [[NSRunLoop currentRunLoop] run];
    }
}

如果有人想知道,我的目标是生成一个动态库,用于JNI项目,不涉及GUI。这是我试图获得一些在Mac上完成蓝牙的方式的经验,并让自己熟悉Objective-C。我来自Linux背景,所以如果可能的话,我更喜欢留在命令行。

提前致谢。

1 个答案:

答案 0 :(得分:0)

感谢上述评论者提供的提示,我可以通过添加对委托对象的强引用来解决问题:

InquiryDelegate* g = [[InquiryDelegate alloc] init];

IOBluetoothDeviceInquiry* di = [[IOBluetoothDeviceInquiry alloc]
                                   initWithDelegate:g];

感谢@Willeke和@Ssswift。