选择 UISegmentedControl 控件会导致 SIGABRT

Posted

技术标签:

【中文标题】选择 UISegmentedControl 控件会导致 SIGABRT【英文标题】:Selecting UISegmentedControl controls result in SIGABRT 【发布时间】:2011-09-21 14:42:35 【问题描述】:

目标是通过使用 UISegmentedControl 使 MKMapView 从 mapType 切换。

但是,当按下其中一个分段控件时,我在输出中得到了这个:

2011-09-21 18:36:39.127 ShutterBug[2022:ec03] -[__NSCFData indexOfObject:]: 无法识别的选择器发送到实例 0x5c90700 2011-09-21 18:36:39.130 ShutterBug[2022:ec03] * 终止应用程序到期 未捕获的异常“NSInvalidArgumentException”,原因: '-[__NSCFData indexOfObject:]: 无法识别的选择器发送到实例 0x5c90700'

这是我的代码的相关部分,在 changeMapType 的第一行获取 SIGABRT:

static NSArray *mapTypeChoices = nil;
#define MAP_STREET @"Street"
#define MAP_SATELLITE @"Satellite"
#define MAP_HYBRID @"Hybrid"

- (UISegmentedControl *)mapTypeSegmentedControl

    if (!mapTypeChoices) mapTypeChoices = [NSArray arrayWithObjects:MAP_STREET, MAP_SATELLITE, MAP_HYBRID, nil];

    UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:mapTypeChoices];
    segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
    [segmentedControl addTarget:self action:@selector(changeMapType:) forControlEvents:UIControlEventValueChanged];

    switch (self.mapView.mapType) 
        case MKMapTypeStandard: segmentedControl.selectedSegmentIndex = [mapTypeChoices indexOfObject:MAP_STREET]; break;
        case MKMapTypeSatellite: segmentedControl.selectedSegmentIndex = [mapTypeChoices indexOfObject:MAP_SATELLITE]; break;
        case MKMapTypeHybrid: segmentedControl.selectedSegmentIndex = [mapTypeChoices indexOfObject:MAP_HYBRID]; break;
    

    return [segmentedControl autorelease];


- (void)changeMapType:(UISegmentedControl *)segmentedControl

    if (segmentedControl.selectedSegmentIndex == [mapTypeChoices indexOfObject:MAP_STREET]) 
        self.mapView.mapType = MKMapTypeStandard;
     else if (segmentedControl.selectedSegmentIndex == [mapTypeChoices indexOfObject:MAP_SATELLITE]) 
        self.mapView.mapType = MKMapTypeSatellite;
     else if (segmentedControl.selectedSegmentIndex == [mapTypeChoices indexOfObject:MAP_HYBRID]) 
        self.mapView.mapType = MKMapTypeHybrid;
    

编辑:调试器向我显示 changeMapType: 仅在按下 UISegmentedController 一次时被调用两次..

【问题讨论】:

【参考方案1】:

您的静态数组 mapTypeChoices 正在自动释放。这不是类属性,因此不会自动保留(假设您已经定义了 retain 属性属性)。不要为NSArray 使用自动释放的初始化程序。请改用-initWithObject:

【讨论】:

确实,以 alloc/init/copy 开头的任何内容都会保留返回的实例。谢谢!【参考方案2】:

mapTypeChoicesmapTypeSegmentedControl 中创建时会自动释放。与此同时,内存已被重新分配给其他东西(NSData),因此当您尝试请求indexOfObject 时它会崩溃。

假设mapTypeChoices 是一个类实例变量,只要retain 在你创建它之后就可以了。 (不过,请记住在 dealloc 上release

【讨论】:

mapTypeChoices 是一个文件级静态变量,所以在-dealloc 中释放它并不是一个好主意。

以上是关于选择 UISegmentedControl 控件会导致 SIGABRT的主要内容,如果未能解决你的问题,请参考以下文章

UISegmentedControl的具体使用

在 UISegmentedControl 上选择和取消选择段?

UITableView 中的 iOS 13 UISegmentedControl 缓存先前的选择

UISegmentedControl 寄存器点击选定的段

如何使黑色 UISegmentedControl 显示为可见的选择突出显示?

为 UISegmentedControl 定义点击事件