假设我不控制服务器发送给我的内容,并且我收到了一大块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相关问题。
答案 0 :(得分:2)
你没有指定足够的信息来确定这是否是一个有用的答案,但如果你有一个来自服务器的大NSString
,然后创建一个副本NSData
,例如dataUsingEncoding:
1}}发送给NSJSONSerialization
然后这将是很多不必要的复制。
如果您要转换为NSData
NSString
(甚至是原始字节),情况也是如此。
理想情况下,您将使用NSData
或dataWithBytesNoCopy: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数据转换为对象,如果它更多是性能问题而不是内存问题。