Objective-C - 处理大量对象分配

时间:2014-10-14 16:10:47

标签: objective-c json performance memory

假设我不控制服务器发送给我的内容,并且我收到了一大块JSON,我必须先创建数千个对象,然后才能在UITableView / UICollectionView中使用它。我如何改善应用程序的性能?

映射到JSON响应的对象示例:

@interface Address : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) Person *person;
...
@end

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) CreditCard *card;
...
@end

@interface CreditCard : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) Bank *bank;
...
@end

回到我身边的JSON数据会有数千个地址,每个地址可以有多个人,每个人可以拥有多张信用卡,依此类推......再一次,我不控制JSON由服务器提供给我的数据源,因此我无法实现数据分块机制。

澄清:对象分配存在瓶颈/性能问题,而不是UITableView / UICollectionView相关问题。

4 个答案:

答案 0 :(得分:2)

你没有指定足够的信息来确定这是否是一个有用的答案,但如果你有一个来自服务器的大NSString,然后创建一个副本NSData,例如dataUsingEncoding: 1}}发送给NSJSONSerialization然后这将是很多不必要的复制。

如果您要转换为NSData NSString(甚至是原始字节),情况也是如此。

理想情况下,您将使用NSDatadataWithBytesNoCopy:length:构建dataWithBytesNoCopy:length:freeWhenDone:实例的服务器返回原始字节缓冲区。然后将此实例传递给NSJSONSerialization

之后,我不确定在没有看到某些代码的情况下告诉你什么。

答案 1 :(得分:1)

我们是否可以说:在您的桌面视图中使用它们之前,不要创建数千个对象?

而不是像。

for(NSDictionary *JSONObject in allJSONObjects)
{
    [array addObject:[MyLocalObject objectWithJSONObject:JSONObject]];
}

dispatch_blah_blah_blah( { [tableViewDataSource haveSomeObjects:array]; } )

...

- (void)haveSomeObjects:(NSArray *)array 
{
    _tableObjects = array;
    [self.tableView reloadData];
}

一起去:

for(NSDictionary *JSONObject in allJSONObjects)
{
    [array addObject:[MyLocalObject objectWithJSONObject:JSONObject]];

    if([array count] == 100)
    {
        dispatch_blah_blah_blah( { [tableViewDataSource addSomeObjects:array]; } )
        [array removeAllObjects];
    }
}

if([array count])
    dispatch_blah_blah_blah( { [tableViewDataSource addSomeObjects:array]; } )

...

- (void)addSomeObjects:(NSArray *)array
{
    NSUInteger oldIndex = [_tableObjects count];
    [_tableObjects addObjectsFromArray:array];

    NSMutableArray *indexPaths = [NSMutableArray array];
    for(NSUInteger index = oldIndex; index < [_tableObjects count]; index++)
        [indexPaths addObject:[NSIndexPath indexPathWithRow:(NSInteger)index column:0]]; 

    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:<whatever>];
}

答案 2 :(得分:1)

NSJSONSerialization将为您创建所有字符串和NSNumbers。除非您设置选项来创建可变对象,否则所有这些NSString对象都是不可变的(无论如何NSNumber都是不可变的)。一旦有了不可变对象,制作副本实际上并不会分配更多内存。

因此,例如,Person对象需要一些内存用于对象本身,但没有额外的内存存储在其中的名称;已经由NSJSONSerialization创建。

答案 3 :(得分:0)

NSJSONSerialization将为您创建所有字符串和NSNumbers。除非您设置选项来创建可变对象,否则所有这些NSString对象都是不可变的(无论如何NSNumber都是不可变的)。一旦有了不可变对象,制作副本实际上并不会分配更多内存。

因此,例如,Person对象需要一些内存用于对象本身,但没有额外的内存存储在其中的名称;已经由NSJSONSerialization创建。

您可以考虑仅在需要时将JSON数据转换为对象,如果它更多是性能问题而不是内存问题。