优化慢速代码 - 字典的枚举

时间:2011-04-26 12:12:26

标签: iphone objective-c json ios

我有以下代码将JSON字符串解码为一个对象数组,然后我可以在UITableView中使用它。

起初我认为JSON解码是一个缓慢的部分,但它似乎并不像“字典完成”几乎立即出现。

关于如何让代码更快一点的任何想法?

-(void)parseJSON:(NSString *)jsonData{

    NSLog(@"Start parsing");
    NSDictionary *deserializedData = [jsonData objectFromJSONString];
    NSLog(@"Dictionary Done");

    NSArray *flights = [deserializedData valueForKeyPath:@"flights.flight"];
    NSMutableArray *localArray = [[NSMutableArray alloc] init ];
    NSString *lastFlightno =@"";

    for (NSDictionary *flight in flights){

        ArchiveFlight *aFlight = [[ArchiveFlight alloc] initWithFlightno:[flight objectForKey:@"flightno"] route:[flight objectForKey:@"route"]];
        aFlight.flightID = [flight objectForKey:@"primary_key"];
        aFlight.timeStamp = [aFlight niceDate:[flight objectForKey:@"timestamp"]];

        if (![lastFlightno isEqualToString:aFlight.flightno]) {
            [localArray addObject:aFlight];
        }

        lastFlightno =aFlight.flightno;
        [aFlight release];
    }
    NSLog(@"End Parsing");
    [self loadupTable:localArray];
    self.flightArray = localArray;
    [localArray release];

}

编辑:添加了时间戳

NSLog的时间戳如下......

2011-04-26 13:22:36.104 App[1778:707] Finished request
2011-04-26 13:22:36.109 App[1778:707] Start parsing
2011-04-26 13:22:36.128 App[1778:707] Dictionary Done
2011-04-26 13:22:37.713 App[1778:707] End Parsing

JSON的示例...

{"flights":[{"flight":{"flightno":"RYR54WP","timestamp":"2011-04-26 12:13:04","route":"EGNX-LEAL","primary_key":"836453"}},{"flight":{"flightno":"RYR24LU","timestamp":"2011-04-26 09:14:03","route":"EVRA-EGNX","primary_key":"831318"}},{"flight":{"flightno":"RYR39WH","timestamp":"2011-04-26 05:33:03","route":"EGNX-EVRA","primary_key":"825492"}},{"flight":{"flightno":"RYR7PX","timestamp":"2011-04-25 20:07:03","route":"LELC-EGNX","primary_key":"816703"}},{"flight":{"flightno":"RYR2VB","timestamp":"2011-04-25 16:57:06","route":"EGNX-LELC","primary_key":"810900"}},{"flight":{"flightno":"RYR3JN","timestamp":"2011-04-25 12:36:04","route":"GCTS-EGNX","primary_key":"802631"}},{"flight":{"flightno":"RYR8GV","timestamp":"2011-04-25 06:07:03","route":"EGNX-GCTS","primary_key":"792945"}},{"flight":{"flightno":"RYR82QR","timestamp":"2011-04-24 19:42:04","route":"EPKK-EGNX","primary_key":"783306"}},{"flight":{"flightno":"RYR51PV","timestamp":"2011-04-24 16:31:05","route":"EGNX-EPKK","primary_key":"777835"}},{"flight":{"flightno":"RYR53AQ","timestamp":"2011-04-24 14:09:05","route":"LIME-EGNX","primary_key":"773572"}},{"flight":{"flightno":"RYR1CX","timestamp":"2011-04-24 11:02:05","route":"EGNX-LIME","primary_key":"768285"}},{"flight":{"flightno":"RYR9ZW","timestamp":"2011-04-24 08:21:04","route":"LEGE-EGNX","primary_key":"764624"}},{"flight":{"flightno":"RYR63BC","timestamp":"2011-04-24 05:48:02","route":"EGNX-LEGE","primary_key":"761726"}},{"flight":{"flightno":"RYR7PX","timestamp":"2011-04-23 19:39:03"

格式化示例:

{
   "flights":[
      {
         "flight":{
            "flightno":"RYR54WP",
            "timestamp":"2011-04-26 12:13:04",
            "route":"EGNX-LEAL",
            "primary_key":"836453"
         }
      },
      {
         "flight":{
            "flightno":"RYR24LU",
            "timestamp":"2011-04-26 09:14:03",
            "route":"EVRA-EGNX",
            "primary_key":"831318"
         }
      }
   ]
}

编辑2:

所以这里是导致经济放缓的“niceDate”!

-(NSString *)niceDate:(NSString *)oldDate{
    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init]autorelease];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *sourceDate = [formatter dateFromString:oldDate];
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateStyle:NSDateFormatterFullStyle];
    [dateFormatter setTimeStyle:NSDateFormatterLongStyle];
    NSString *timeString = [dateFormatter stringFromDate:sourceDate];
    return [NSString stringWithFormat:@"%@",timeString];
}

1 个答案:

答案 0 :(得分:3)

有些事情会浮现在脑海中:

NSArray *flights = [deserializedData valueForKeyPath:@"flights.flight"];

您需要使用KVC吗?您的JSON数据的结构是什么?

ArchiveFlight *aFlight = [[ArchiveFlight alloc] initWithFlightno:[flight objectForKey:@"flightno"] route:[flight objectForKey:@"route"]];
aFlight.flightID = [flight objectForKey:@"primary_key"];
aFlight.timeStamp = [aFlight niceDate:[flight objectForKey:@"timestamp"]];

您始终创建ArchiveFlight的实例并解析时间戳...

    if (![lastFlightno isEqualToString:aFlight.flightno]) {
        [localArray addObject:aFlight];
    }

......即使你不必一直这样做。根据您拥有的重复flightnos的数量,这可能会产生明显的差异。

为什么不阅读[flight objectForKey:@"flightno"],将其与lastFlightno进行比较,当且仅当它们不同时,创建一个实例,将其添加到数组中并释放它?


修改:尝试使用以下无KVC代码:

NSArray *flights = [deserializedData objectForKey:@"flights"];
NSMutableArray *localArray = [[NSMutableArray alloc] init ];
NSString *lastFlightno =@"";

for (NSDictionary *flightWrapper in flights) {
    NSDictionary *flight = [flightWrapper objectForKey:@"flight"];
    NSString *flightno = [flight objectForKey:@"flightno"];

    if (! [flightno isEqual:lastFlightno]) {
        // create instance, add it to the array, release the instance
    }
}

编辑:您正在此方法中创建和(自动)发布NSDateFormatter的两个实例。一般情况下这是可以的,但由于执行时间> 1K次,因此有两个注意事项:a)你正在创建/使用/释放这两个实例> 1K次,事实上,你没有两个,b)你应该在循环中使用自动释放池。

您应该将此方法设为类方法(或函数),因为它不依赖于该类的实例的状态。您的格式化程序将是类(静态)变量。例如:

@implementation ArchiveFlight

static NSDateFormatter *formatter1; // choose better names!
static NSDateFormatter *formatter2;

+ (void)initialize {
    if (self == [ArchiveFlight class]) {
        formatter1 = [[NSDateFormatter alloc] init];
        [formatter1 setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

        formatter2 = [[NSDateFormatter alloc] init];
        [formatter2 setDateStyle:NSDateFormatterFullStyle];
        [formatter2 setTimeStyle:NSDateFormatterLongStyle];
    }
}

+ (NSString *)niceDate:(NSString *)oldDate {
    NSDate *sourceDate = [formatter1 dateFromString:oldDate];
    NSString *timeString = [formatter2 stringFromDate:sourceDate];
    return timeString;
    // why +stringWithFormat:? It’s not necessary!
    // return [NSString stringWithFormat:@"%@",timeString];
}

这修复了项目a)但你真的应该在循环中使用自动释放池,因为你正在使用的Cocoa方法返回自动释放的对象。通过在循环的每次迭代中使用自动释放池,可以减少代码的内存占用 - 尽管也可以降低性能。我建议您尝试使用和不使用内部自动释放池。

for (NSDictionary *flightWrapper in flights) {
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    …

    [pool drain];
}