【问题标题】:ios application crashes randomlyios应用程序随机崩溃
【发布时间】:2014-03-20 14:02:19
【问题描述】:

我有一个使用此行加载的 NSMutableArray (timeZoneTree)

timeZoneTree = [[Timezone getTimeZoneTree] retain];

时区的定义是

@interface Timezone : NSObject 
{
    NSString *name;
    int rawOffset;
}

getTimeZoneTree 方法如下:

+ (NSMutableArray*) getTimeZoneTree
{
    if (offsetGroups == nil)
    {
        // initialize a new mutable array
        offsetGroups = [[[NSMutableArray alloc] init] autorelease];

        // build the path to the timezones file
        NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"TimeZones.dat"];

        // get the data of the file
        NSData *data = [[NSData alloc] initWithContentsOfFile:path];
        BufferReader *reader = [[BufferReader alloc] initWithBuffer:(const char*)[data bytes] length:[data length]];

        OffsetGroup *curOffsetGroup;
        RegionGroup *curRegionGroup;

        int offsetGroupCount = [reader readInt32];

        // go through all raw offset groups
        for(int curOffsetGroupIndex=0; curOffsetGroupIndex<offsetGroupCount; ++curOffsetGroupIndex)
        {
            int rawOffset = [reader readInt32];

            // initialize a new offset group
            curOffsetGroup = [[OffsetGroup alloc] init];
            curOffsetGroup.rawOffset = rawOffset;

            // and add it to the offset groups
            [offsetGroups addObject:curOffsetGroup]; 

            int regionGroupCount = [reader readInt32];

            // go through all region group of the war offset group
            for(int curRegionGroupIndex=0; curRegionGroupIndex<regionGroupCount; ++curRegionGroupIndex)
            {
                int regionNameLength = [reader readInt8];
                char *regionNameUTF8 = malloc(regionNameLength + 1);
                [reader readBytes:regionNameUTF8 withLength:regionNameLength];
                regionNameUTF8[regionNameLength] = '\0';

                // initialize a new region group
                curRegionGroup = [[RegionGroup alloc] init];
                curRegionGroup.name = [NSString stringWithCString:regionNameUTF8 encoding:NSUTF8StringEncoding];

                // and add it to the region groups of the offset group
                [curOffsetGroup.regionGroups addObject:curRegionGroup];

                int timeZoneCount = [reader readInt32];

                // go through all time zones 
                for(int curTimeZoneIndex=0; curTimeZoneIndex<timeZoneCount; ++curTimeZoneIndex)
                {
                    int timeZoneNameLength = [reader readInt8];

                    char *timeZoneNameUTF8 = malloc(timeZoneNameLength+1);
                    [reader readBytes:timeZoneNameUTF8 withLength:timeZoneNameLength];
                    timeZoneNameUTF8[timeZoneNameLength] = '\0';

                    // create a new time zone name
                    NSString *timeZoneName = [NSString stringWithCString:timeZoneNameUTF8 encoding:NSUTF8StringEncoding];

                    // if the name is not nil
                    if (timeZoneName != nil) 
                        // then add it to the region group
                        [curRegionGroup.timeZones addObject:timeZoneName];

                    free(timeZoneNameUTF8);
                }
                [curRegionGroup release];
                free(regionNameUTF8);
            }
            [curOffsetGroup release];
        }
        [reader release];
        [data release];
    }

    return offsetGroups;
}

有什么问题?为什么代码有时会在这一行崩溃?我正在使用 ROOTSDK 7.0 构建

【问题讨论】:

  • 错误是什么,堆栈跟踪在哪里?
  • timeZoneTree = [[Timezone getTimeZoneTree] 保留];崩溃
  • 尝试删除自动释放
  • 您正在返回一个未在函数内部声明的对象(offsetGroups)。谁知道谁在这个范围之外保留/释放它?删除自动释放可能会解决崩溃,但我会重构整个函数以更改/本地化范围。

标签: ios iphone objective-c ios7


【解决方案1】:

我会说这是autorelease 在似乎是一个全局变量中的使用:

offsetGroups = [[[NSMutableArray alloc] init] autorelease];
//                                            ^^^^^^^^^^^

这意味着一旦线程遇到自动释放池耗尽(可能在运行循环中),数组就会被释放。

去掉autorelease的使用,如果这样做需要去掉第一行代码的retain

【讨论】:

  • 即使是autoreleased 它仍然被保留...检查他的第一行代码
  • @Merlevede 对不起,我没有关注。 timeZoneTreeoffsetGroups 有什么关系?
  • 一切! offsetGroups 由该函数返回(自动释放)并分配给 timeZoneTree(保留)。
  • @Merlevede 那么为什么它是一个实例变量,而不是一个局部变量呢?是否有可能在对象的其他地方使用它?
  • @Merlevede 更正;它必须是全局变量,因为该方法是类方法。 OP 假定它是 retaind,但是一旦它在外部是 released,它将是一个悬空指针。
猜你喜欢
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
相关资源
最近更新 更多