为什么我经常在此代码中获得ExcBadAccess:

时间:2014-03-24 05:56:24

标签: c++ objective-c xcode5

我使用ARC

NSAttributedString * arString = [self asSchedule:arTimes];
self.lblTimeLeft.attributedText = arString;

没有给出太多信息。它直接进入主

int main(int argc, char *argv[])
{
    @autoreleasepool {
        //int retVal = UIApplicationMain(argc, argv, nil, nil);
         int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([newIsiKotaAppDelegate class]));
        return retVal;
    }
}

我设法发现最后执行的代码是这样的:     self.lblTimeLeft.attributedText = arString;

我提供了额外的代码来测试

    NSAttributedString * arString = [self asSchedule:arTimes];
    self.lblTimeLeft.attributedText = arString;


    PO1(@"Hello World");
    while(false);// Error happen after this code is executed
}

代码是提供UITableViewCell显示的例程的一部分。所以错误发生在

之后
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = indexPath.row;

    NSDictionary * rowDictionary = _marManagedObjectArray [row];

    BGCinemaScheduleCell * BCS = [[BGCinemaScheduleCell alloc]init];

    BCS.dicCinemaDictionary =rowDictionary;

    return BCS; //This is where the error happen
}

似乎NSAttributedString工作正常,直到它实际显示或其他东西。

错误似乎发生在

TAttributes::TAttributes(__CFDictionary const *)

asSchedule的内容通常是

-(NSAttributedString *) asSchedule:(NSArray *) arTimes
{
    NSMutableArray * timeBefore = [NSMutableArray array];
    NSMutableArray * timeAfter = [NSMutableArray array];

    for (NSString * strTime in arTimes) {

        NSDate * date = [NSDate dtWithCurrentDateAndProvidedTime: strTime];
        NSTimeInterval dblInterval =[date timeIntervalSinceNow];
        if (dblInterval>0)
        {
            [timeAfter addObject:strTime];
        }
        else{
            [timeBefore addObject:strTime];
        }
    }

    NSString * strTimeBefore = [timeBefore componentsJoinedByString:@" "];
    NSString * strTimeAfter = [timeAfter componentsJoinedByString:@" "];

    NSString *yourString = [NSString stringWithFormat:@"%@ %@", strTimeBefore, strTimeAfter];
                            // start at the end of strTimeBefore and go the length of strTimeAfter
    NSRange boldedRange = NSMakeRange([strTimeBefore length] + 1, [strTimeAfter length]);
    NSString *boldFontName = [[UIFont boldSystemFontOfSize:12] fontName];

    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:yourString];
    [attrString addAttribute:NSFontAttributeName value:boldFontName range:boldedRange];

    PO1(NSStringFromRange(boldedRange));
    PO1(@(attrString.length));
    return attrString;
}

更新

我改变了self.lblTimeLeft.attributedText = arString; to self.lblTimeLeft.attributedText = arString.copy;无济于事。

我想知道这可能是问题所在: [attrString addAttribute:NSFontAttributeName value:boldFontName range:boldedRange];

我认为原始样本使用KCFont而不是NSFontAttributeName

3 个答案:

答案 0 :(得分:1)

无法从代码中判断您的项目是否使用ARC,但看起来您的asSchedule方法返回一个refcount为0的字符串。由您保留对该字符串的引用,无论是旧学校使用保留关键字(可能是一个坏主意)或将其分配给使用关键字声明的属性(或保留,如果预先ARC)。

调试这些东西的最佳工具是Instruments,使用Zombies检查。如果我在你的引用计数命中0并且内存已被释放后尝试使用该字符串是正确的,那么你将看到refcount增量和减量的历史非常清楚。

答案 1 :(得分:1)

你快到了那里:

  

我想知道这是否可能是问题所在:[attrString addAttribute:NSFontAttributeName value:boldFontName range:boldedRange];

您的代码说:

NSString *boldFontName = [[UIFont boldSystemFontOfSize:12] fontName];
...
[attrString addAttribute:NSFontAttributeName value:boldFontName range:boldedRange];

应该说:

UIFont *boldFont = [UIFont boldSystemFontOfSize:12];
...
[attrString addAttribute:NSFontAttributeName value:boldFont range:boldedRange];

根据文档的表1(下面的链接)和我自己的应用程序代码,您应该传递NSFont而不是字体名称。

https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html#//apple_ref/doc/uid/TP40004903-SW2

答案 2 :(得分:-1)

尝试分配并启动Attributedstring,然后将其分配给self.lblTimeLeft.attributedText