You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置UICollectionViewCell边框颜色时App触发EXC_BREAKPOINT崩溃

问题

我编写了一段代码,通过定时改变UICollectionViewCell的边框颜色实现闪烁效果。闪烁序列开始时会保存单元格的原始边框颜色,以便序列结束后恢复。但目前代码触发崩溃,报错信息为Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1831e1fd4),且调试现象不符合预期。

注:这段代码此前测试正常,不清楚为何突然崩溃。

相关代码如下:

@interface OrderCollectionViewCell : UICollectionViewCell 

               .   .   .

@property (strong, nonatomic) NSTimer *borderTimer;
@property (nonatomic) BOOL blinkStatus;
@property (nonatomic) NSInteger blinkTimes;

               .   .   .

@implementation OrderCollectionViewCell
{
    CGColorRef normalBorder;
}

-(void)flashBorder
{
    // Save original color for later restore
    normalBorder = self.bg.layer.borderColor;
    
    if(self.borderTimer) {
        [self.borderTimer invalidate];
    }
    self.borderTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(blink) userInfo:nil repeats:YES];
    
    [[NSRunLoop mainRunLoop] addTimer:self.borderTimer forMode:NSRunLoopCommonModes];
    
    self.blinkTimes = 0;
    self.blinkStatus = NO;
}


-(void)blink
{
    if (self.blinkTimes++ == 3)
    {
        // Sequence complete.  Restore original color
        self.bg.layer.borderColor = normalBorder;  // <-- This line crashes
        [self.borderTimer invalidate];
        self.borderTimer = nil;
        return;
    }
    
    if(self.blinkStatus == NO){
        self.bg.layer.borderColor = [UIColor whiteColor].CGColor;
        self.blinkStatus = YES;
    }else {
        self.bg.layer.borderColor = [UIColor orangeColor].CGColor;
        self.blinkStatus = NO;
    }
}

奇怪的是,根据Apple文档,CGColorRef是结构体而非对象,但调试时self.bg.layer.borderColor和normalBorder显示为<CGColor 0x281b6d200>这类类似对象的地址格式。当恢复颜色时,normalBorder仅显示地址,无有效颜色数据。

请问是什么原因导致该崩溃?为何调试中CGColorRef表现得像对象而非结构体?


原因分析与解决方案

崩溃原因

CGColorRef属于Core Foundation(CF)对象,虽然文档将其定义为结构体,但本质是遵循CF引用计数规则的对象。你直接将self.bg.layer.borderColor赋值给normalBorder时,没有增加它的引用计数,后续系统可能会释放这个CGColor,导致normalBorder变成野指针,赋值时触发崩溃。此外,多次调用flashBorder时,旧的normalBorder未被释放,还会引发内存泄漏。

关于CGColorRef调试显示的问题

调试器对CF对象做了特殊处理,会以类似Objective-C对象的格式(<CGColor 地址>)展示,方便开发者查看,但它本质还是依赖引用计数管理的CF对象,并非纯结构体。

修复代码

修改代码,正确管理CGColorRef的引用计数:

@implementation OrderCollectionViewCell
{
    CGColorRef normalBorder;
}

-(void)flashBorder
{
    // 先释放旧的颜色,避免内存泄漏
    if (normalBorder) {
        CFRelease(normalBorder);
        normalBorder = NULL;
    }
    // 保存原始颜色并增加引用计数
    normalBorder = CGColorRetain(self.bg.layer.borderColor);
    
    if(self.borderTimer) {
        [self.borderTimer invalidate];
        self.borderTimer = nil;
    }
    self.borderTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(blink) userInfo:nil repeats:YES];
    
    [[NSRunLoop mainRunLoop] addTimer:self.borderTimer forMode:NSRunLoopCommonModes];
    
    self.blinkTimes = 0;
    self.blinkStatus = NO;
}


-(void)blink
{
    if (self.blinkTimes++ == 3)
    {
        // 恢复原始颜色
        self.bg.layer.borderColor = normalBorder;
        // 释放保存的颜色
        CFRelease(normalBorder);
        normalBorder = NULL;
        
        [self.borderTimer invalidate];
        self.borderTimer = nil;
        return;
    }
    
    if(!self.blinkStatus){
        self.bg.layer.borderColor = [UIColor whiteColor].CGColor;
        self.blinkStatus = YES;
    }else {
        self.bg.layer.borderColor = [UIColor orangeColor].CGColor;
        self.blinkStatus = NO;
    }
}

// 销毁cell时清理资源
- (void)dealloc {
    if (normalBorder) {
        CFRelease(normalBorder);
    }
    if (self.borderTimer) {
        [self.borderTimer invalidate];
    }
}

额外优化建议

可以改用UIColor保存原始颜色,避开直接操作CGColorRef,更符合Objective-C的内存管理习惯:

// 将成员变量替换为UIColor类型
@property (nonatomic, strong) UIColor *normalBorderColor;

-(void)flashBorder
{
    self.normalBorderColor = [UIColor colorWithCGColor:self.bg.layer.borderColor];
    
    // 其余代码不变
}

-(void)blink
{
    if (self.blinkTimes++ == 3)
    {
        self.bg.layer.borderColor = self.normalBorderColor.CGColor;
        // 其余代码不变
    }
    // 其余代码不变
}

内容的提问来源于stack exchange,提问作者Agent Friday

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:36:01