HINSPRefHistoryTableViewController.m 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // RMRefHistoryTableViewController.m
  3. // HeapInspectorExample
  4. //
  5. // Created by Christian Menschel on 11.09.14.
  6. // Copyright (c) 2014 tapwork. All rights reserved.
  7. //
  8. #import "HINSPRefHistoryTableViewController.h"
  9. #import "NSObject+HeapInspector.h"
  10. #import "HINSPTableViewCell.h"
  11. #import "HINSPTableViewController.h"
  12. @interface HINSPRefHistoryTableViewController ()
  13. @end
  14. @implementation HINSPRefHistoryTableViewController
  15. #pragma mark - Init
  16. - (instancetype)initWithObject:(id)object
  17. {
  18. self = [super initWithObject:object];
  19. if (self) {
  20. self.title = [NSString stringWithFormat:@"Reference History: %s: %p",
  21. object_getClassName(self.inspectingObject),
  22. self.inspectingObject];
  23. NSArray *dataSource = [NSObject referenceHistoryForObject:object];
  24. self.dataSource = dataSource;
  25. }
  26. return self;
  27. }
  28. #pragma mark - View Life Cycle
  29. static const CGFloat kHeaderViewHeight = 70;
  30. - (void)viewDidLoad
  31. {
  32. [super viewDidLoad];
  33. UIView *headerView = [[UIView alloc] init];
  34. headerView.frame = CGRectMake(0, 0, self.view.bounds.size.width, kHeaderViewHeight);
  35. headerView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
  36. headerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  37. NSPredicate *predicate0 = [NSPredicate predicateWithFormat:@"SELF == 'alloc'"];
  38. NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF == 'retain'"];
  39. NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"SELF == 'storeStrong'"];
  40. NSPredicate *predicate3 = [NSPredicate predicateWithFormat:@"SELF == 'release'"];
  41. NSArray *allocs = [[self.dataSource valueForKey:@"type"] filteredArrayUsingPredicate:predicate0];
  42. NSArray *retains = [[self.dataSource valueForKey:@"type"] filteredArrayUsingPredicate:predicate1];
  43. NSArray *strongs = [[self.dataSource valueForKey:@"type"] filteredArrayUsingPredicate:predicate2];
  44. NSArray *releases = [[self.dataSource valueForKey:@"type"] filteredArrayUsingPredicate:predicate3];
  45. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,8,headerView.bounds.size.width,20.0)];
  46. label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
  47. label.font = [UIFont systemFontOfSize:10];
  48. label.numberOfLines = 1;
  49. label.textAlignment = NSTextAlignmentCenter;
  50. NSInteger count = [allocs count] + [retains count] + [strongs count] - [releases count];
  51. label.text = [NSString stringWithFormat:@"Retain Count: %ld Alloc: %lu Retain: %lu Strong: %lu Release: %lu",
  52. (long)count,
  53. (unsigned long)[allocs count],
  54. (unsigned long)[retains count],
  55. (unsigned long)[strongs count],
  56. (unsigned long)[releases count]];
  57. [headerView addSubview:label];
  58. UIView *superTableHeaderView = self.tableView.tableHeaderView;
  59. self.tableView.tableHeaderView = nil;
  60. CGRect tableHeaderViewFrame = superTableHeaderView.frame;
  61. tableHeaderViewFrame.origin.y = CGRectGetMaxY(label.frame);
  62. superTableHeaderView.frame = tableHeaderViewFrame;
  63. [headerView addSubview:superTableHeaderView];
  64. self.tableView.tableHeaderView = headerView;
  65. }
  66. #pragma mark - TableView
  67. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  68. {
  69. HINSPTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kTableViewCellIdent
  70. forIndexPath:indexPath];
  71. NSDictionary *item = self.dataSource[indexPath.row];
  72. cell.textLabel.text = [NSString stringWithFormat:@"%ld %@",(long)indexPath.row, item[@"type"]];
  73. cell.detailTextLabel.text = item[@"last_trace"];
  74. NSArray *backtrace = item[@"all_traces"];
  75. if ([backtrace count] > 0) {
  76. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  77. cell.userInteractionEnabled = YES;
  78. } else {
  79. cell.accessoryType = UITableViewCellAccessoryNone;
  80. cell.userInteractionEnabled = NO;
  81. }
  82. return cell;
  83. }
  84. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  85. {
  86. NSDictionary *item = self.dataSource[indexPath.row];
  87. NSArray *backtrace = item[@"all_traces"];
  88. if ([backtrace count] > 0) {
  89. HINSPTableViewController *detailVC = [[HINSPTableViewController alloc] initWithDataSource:backtrace];
  90. detailVC.title = [NSString stringWithFormat:@"%@'s backtrace",item[@"type"]];
  91. [self.navigationController pushViewController:detailVC animated:YES];
  92. }
  93. [tableView deselectRowAtIndexPath:indexPath animated:NO];
  94. }
  95. #pragma mark - Search
  96. - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
  97. {
  98. NSMutableArray *dataSource = [self.dataSourceUnfiltered mutableCopy];
  99. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  100. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type contains[cd] %@ OR last_trace contains[cd] %@",
  101. searchText,searchText];
  102. [dataSource filterUsingPredicate:predicate];
  103. dispatch_async(dispatch_get_main_queue(), ^{
  104. self.dataSource = dataSource;
  105. [self.tableView reloadData];
  106. });
  107. });
  108. }
  109. @end