简体   繁体   English

iOS应用程序随机崩溃

[英]ios application crashes randomly

I have an NSMutableArray (timeZoneTree) that is loaded using this line 我有使用此行加载的NSMutableArray(timeZoneTree)

timeZoneTree = [[Timezone getTimeZoneTree] retain];

The definition of Timezone is 时区的定义是

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

and the getTimeZoneTree method is the following: 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;
}

What is the problem? 问题是什么? Why the code crashed sometimes on this line? 为什么有时代码在此行崩溃? I am building with ROOTSDK 7.0 我正在用ROOTSDK 7.0构建

I'd say it was the use of autorelease in what appears to be an global variable: 我想说的是在似乎是全局变量的情况下使用了autorelease

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

This means as soon as the thread hits an autorelease pool drain (in the run loop, probably) the array is released. 这意味着一旦线程遇到自动释放池耗尽(可能在运行循环中),就会释放阵列。

Remove the use of autorelease , and if you do this you need to remove the retain on the first line of code. 删除对autorelease的使用,如果这样做,则需要删除代码第一行的retain

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM