Преглед изворни кода

Additional object explorer scopes

Scopes now include:
- No inheritance (base class)
- Base class with parent attributes
- Base class with all inherited attributes, except NSObject
- NSObject attributes only

It is unusual that you need to see anything but the parent's attributes alongside those of the base class, and you especially rarely need to see NSObject attributes.
Tanner Bennett пре 8 година
родитељ
комит
d6b5e8c77d
1 измењених фајлова са 140 додато и 57 уклоњено
  1. 140 57
      Classes/ObjectExplorers/FLEXObjectExplorerViewController.m

+ 140 - 57
Classes/ObjectExplorers/FLEXObjectExplorerViewController.m

@@ -17,6 +17,20 @@
 #import "FLEXInstancesTableViewController.h"
 #import "FLEXInstancesTableViewController.h"
 #import <objc/runtime.h>
 #import <objc/runtime.h>
 
 
+typedef NS_ENUM(NSUInteger, FLEXObjectExplorerScope) {
+    FLEXObjectExplorerScopeNoInheritance,
+    FLEXObjectExplorerScopeWithParent,
+    FLEXObjectExplorerScopeAllButNSObject,
+    FLEXObjectExplorerScopeNSObjectOnly
+};
+
+typedef NS_ENUM(NSUInteger, FLEXMetadataKind) {
+    FLEXMetadataKindProperties,
+    FLEXMetadataKindIvars,
+    FLEXMetadataKindMethods,
+    FLEXMetadataKindClassMethods
+};
+
 // Convenience boxes to keep runtime properties, ivars, and methods in foundation collections.
 // Convenience boxes to keep runtime properties, ivars, and methods in foundation collections.
 @interface FLEXPropertyBox : NSObject
 @interface FLEXPropertyBox : NSObject
 @property (nonatomic, assign) objc_property_t property;
 @property (nonatomic, assign) objc_property_t property;
@@ -36,25 +50,30 @@
 @implementation FLEXMethodBox
 @implementation FLEXMethodBox
 @end
 @end
 
 
-static const NSInteger kFLEXObjectExplorerScopeNoInheritanceIndex = 0;
-static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
-
 @interface FLEXObjectExplorerViewController () <UISearchBarDelegate>
 @interface FLEXObjectExplorerViewController () <UISearchBarDelegate>
 
 
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *properties;
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *properties;
+@property (nonatomic, strong) NSArray<FLEXPropertyBox *> *propertiesWithParent;
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *inheritedProperties;
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *inheritedProperties;
+@property (nonatomic, strong) NSArray<FLEXPropertyBox *> *NSObjectProperties;
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *filteredProperties;
 @property (nonatomic, strong) NSArray<FLEXPropertyBox *> *filteredProperties;
 
 
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *ivars;
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *ivars;
+@property (nonatomic, strong) NSArray<FLEXIvarBox *> *ivarsWithParent;
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *inheritedIvars;
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *inheritedIvars;
+@property (nonatomic, strong) NSArray<FLEXIvarBox *> *NSObjectIvars;
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *filteredIvars;
 @property (nonatomic, strong) NSArray<FLEXIvarBox *> *filteredIvars;
 
 
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *methods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *methods;
+@property (nonatomic, strong) NSArray<FLEXMethodBox *> *methodsWithParent;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *inheritedMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *inheritedMethods;
+@property (nonatomic, strong) NSArray<FLEXMethodBox *> *NSObjectMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *filteredMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *filteredMethods;
 
 
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *classMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *classMethods;
+@property (nonatomic, strong) NSArray<FLEXMethodBox *> *classMethodsWithParent;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *inheritedClassMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *inheritedClassMethods;
+@property (nonatomic, strong) NSArray<FLEXMethodBox *> *NSObjectClassMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *filteredClassMethods;
 @property (nonatomic, strong) NSArray<FLEXMethodBox *> *filteredClassMethods;
 
 
 @property (nonatomic, strong) NSArray<Class> *superclasses;
 @property (nonatomic, strong) NSArray<Class> *superclasses;
@@ -65,7 +84,7 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 
 
 @property (nonatomic, strong) UISearchBar *searchBar;
 @property (nonatomic, strong) UISearchBar *searchBar;
 @property (nonatomic, strong) NSString *filterText;
 @property (nonatomic, strong) NSString *filterText;
-@property (nonatomic, assign) BOOL includeInheritance;
+@property (nonatomic, assign) FLEXObjectExplorerScope scope;
 
 
 @end
 @end
 
 
@@ -85,8 +104,7 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText];
     self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText];
     self.searchBar.delegate = self;
     self.searchBar.delegate = self;
     self.searchBar.showsScopeBar = YES;
     self.searchBar.showsScopeBar = YES;
-    self.searchBar.scopeButtonTitles = @[@"No Inheritance", @"Include Inheritance"];
-    [self.searchBar sizeToFit];
+    [self refreshScopeTitles];
     self.tableView.tableHeaderView = self.searchBar;
     self.tableView.tableHeaderView = self.searchBar;
     
     
     self.refreshControl = [[UIRefreshControl alloc] init];
     self.refreshControl = [[UIRefreshControl alloc] init];
@@ -116,6 +134,28 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 
 
 #pragma mark - Search
 #pragma mark - Search
 
 
+- (void)refreshScopeTitles {
+    if (!self.searchBar) return;
+
+    Class parent = [self.object superclass];
+    Class parentSuper = [parent superclass];
+
+    NSMutableArray *scopes = [NSMutableArray arrayWithObject:@"Base"];
+    if (parent) {
+        [scopes addObject:@"+ Parent"];
+    }
+    if (parentSuper && parentSuper != [NSObject class]) {
+        [scopes addObject:@"+ Inherited"];
+    }
+    if ([self.object isKindOfClass:[NSObject class]]) {
+        [scopes addObject:@"NSObject"];
+    }
+
+    self.searchBar.scopeButtonTitles = scopes;
+    [self.searchBar sizeToFit];
+    [self updateTableData];
+}
+
 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
 {
 {
     self.filterText = searchText;
     self.filterText = searchText;
@@ -128,13 +168,62 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 
 
 - (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
 - (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
 {
 {
-    if (selectedScope == kFLEXObjectExplorerScopeIncludeInheritanceIndex) {
-        self.includeInheritance = YES;
-    } else if (selectedScope == kFLEXObjectExplorerScopeNoInheritanceIndex) {
-        self.includeInheritance = NO;
+    self.scope = selectedScope;
+    [self updateDisplayedData];
+}
+
+- (NSArray *)metadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope {
+    switch (metadataKind) {
+        case FLEXMetadataKindProperties:
+            switch (self.scope) {
+                case FLEXObjectExplorerScopeNoInheritance:
+                    return self.properties;
+                case FLEXObjectExplorerScopeWithParent:
+                    return self.propertiesWithParent;
+                case FLEXObjectExplorerScopeAllButNSObject:
+                    return self.inheritedProperties;
+                case FLEXObjectExplorerScopeNSObjectOnly:
+                    return self.NSObjectProperties;
+            }
+        case FLEXMetadataKindIvars:
+            switch (self.scope) {
+                case FLEXObjectExplorerScopeNoInheritance:
+                    return self.ivars;
+                case FLEXObjectExplorerScopeWithParent:
+                    return self.ivarsWithParent;
+                case FLEXObjectExplorerScopeAllButNSObject:
+                    return self.inheritedIvars;
+                case FLEXObjectExplorerScopeNSObjectOnly:
+                    return self.NSObjectIvars;
+            }
+        case FLEXMetadataKindMethods:
+            switch (self.scope) {
+                case FLEXObjectExplorerScopeNoInheritance:
+                    return self.methods;
+                case FLEXObjectExplorerScopeWithParent:
+                    return self.methodsWithParent;
+                case FLEXObjectExplorerScopeAllButNSObject:
+                    return self.inheritedMethods;
+                case FLEXObjectExplorerScopeNSObjectOnly:
+                    return self.NSObjectMethods;
+            }
+        case FLEXMetadataKindClassMethods:
+            switch (self.scope) {
+                case FLEXObjectExplorerScopeNoInheritance:
+                    return self.classMethods;
+                case FLEXObjectExplorerScopeWithParent:
+                    return self.classMethodsWithParent;
+                case FLEXObjectExplorerScopeAllButNSObject:
+                    return self.inheritedClassMethods;
+                case FLEXObjectExplorerScopeNSObjectOnly:
+                    return self.NSObjectClassMethods;
+            }
     }
     }
 }
 }
 
 
+- (NSInteger)totalCountOfMetadata:(FLEXMetadataKind)metadataKind forScope:(FLEXObjectExplorerScope)scope {
+    return [self metadata:metadataKind forScope:scope].count;
+}
 
 
 #pragma mark - Setter overrides
 #pragma mark - Setter overrides
 
 
@@ -143,15 +232,7 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     _object = object;
     _object = object;
     // Use [object class] here rather than object_getClass because we don't want to show the KVO prefix for observed objects.
     // Use [object class] here rather than object_getClass because we don't want to show the KVO prefix for observed objects.
     self.title = [[object class] description];
     self.title = [[object class] description];
-    [self updateTableData];
-}
-
-- (void)setIncludeInheritance:(BOOL)includeInheritance
-{
-    if (_includeInheritance != includeInheritance) {
-        _includeInheritance = includeInheritance;
-        [self updateDisplayedData];
-    }
+    [self refreshScopeTitles];
 }
 }
 
 
 - (void)setFilterText:(NSString *)filterText
 - (void)setFilterText:(NSString *)filterText
@@ -215,11 +296,17 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 {
 {
     Class class = [self.object class];
     Class class = [self.object class];
     self.properties = [[self class] propertiesForClass:class];
     self.properties = [[self class] propertiesForClass:class];
-    self.inheritedProperties = [[self class] inheritedPropertiesForClass:class];
+    self.propertiesWithParent = [self.properties arrayByAddingObjectsFromArray:[[self class] propertiesForClass:[class superclass]]];
+    self.inheritedProperties = [self.properties arrayByAddingObjectsFromArray:[[self class] inheritedPropertiesForClass:class]];
+    self.NSObjectProperties = [[self class] propertiesForClass:[NSObject class]];
 }
 }
 
 
 + (NSArray<FLEXPropertyBox *> *)propertiesForClass:(Class)class
 + (NSArray<FLEXPropertyBox *> *)propertiesForClass:(Class)class
 {
 {
+    if (!class) {
+        return @[];
+    }
+    
     NSMutableArray<FLEXPropertyBox *> *boxedProperties = [NSMutableArray array];
     NSMutableArray<FLEXPropertyBox *> *boxedProperties = [NSMutableArray array];
     unsigned int propertyCount = 0;
     unsigned int propertyCount = 0;
     objc_property_t *propertyList = class_copyPropertyList(class, &propertyCount);
     objc_property_t *propertyList = class_copyPropertyList(class, &propertyCount);
@@ -234,10 +321,11 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     return boxedProperties;
     return boxedProperties;
 }
 }
 
 
+/// Skips NSObject
 + (NSArray<FLEXPropertyBox *> *)inheritedPropertiesForClass:(Class)class
 + (NSArray<FLEXPropertyBox *> *)inheritedPropertiesForClass:(Class)class
 {
 {
     NSMutableArray<FLEXPropertyBox *> *inheritedProperties = [NSMutableArray array];
     NSMutableArray<FLEXPropertyBox *> *inheritedProperties = [NSMutableArray array];
-    while ((class = [class superclass])) {
+    while ((class = [class superclass]) && class != [NSObject class]) {
         [inheritedProperties addObjectsFromArray:[self propertiesForClass:class]];
         [inheritedProperties addObjectsFromArray:[self propertiesForClass:class]];
     }
     }
     return inheritedProperties;
     return inheritedProperties;
@@ -245,10 +333,7 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 
 
 - (void)updateFilteredProperties
 - (void)updateFilteredProperties
 {
 {
-    NSArray<FLEXPropertyBox *> *candidateProperties = self.properties;
-    if (self.includeInheritance) {
-        candidateProperties = [candidateProperties arrayByAddingObjectsFromArray:self.inheritedProperties];
-    }
+    NSArray<FLEXPropertyBox *> *candidateProperties = [self metadata:FLEXMetadataKindProperties forScope:self.scope];
     
     
     NSArray<FLEXPropertyBox *> *unsortedFilteredProperties = nil;
     NSArray<FLEXPropertyBox *> *unsortedFilteredProperties = nil;
     if ([self.filterText length] > 0) {
     if ([self.filterText length] > 0) {
@@ -294,11 +379,16 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 {
 {
     Class class = [self.object class];
     Class class = [self.object class];
     self.ivars = [[self class] ivarsForClass:class];
     self.ivars = [[self class] ivarsForClass:class];
-    self.inheritedIvars = [[self class] inheritedIvarsForClass:class];
+    self.ivarsWithParent = [self.ivars arrayByAddingObjectsFromArray:[[self class] ivarsForClass:[class superclass]]];
+    self.inheritedIvars = [self.ivars arrayByAddingObjectsFromArray:[[self class] inheritedIvarsForClass:class]];
+    self.NSObjectIvars = [[self class] ivarsForClass:[NSObject class]];
 }
 }
 
 
 + (NSArray<FLEXIvarBox *> *)ivarsForClass:(Class)class
 + (NSArray<FLEXIvarBox *> *)ivarsForClass:(Class)class
 {
 {
+    if (!class) {
+        return @[];
+    }
     NSMutableArray<FLEXIvarBox *> *boxedIvars = [NSMutableArray array];
     NSMutableArray<FLEXIvarBox *> *boxedIvars = [NSMutableArray array];
     unsigned int ivarCount = 0;
     unsigned int ivarCount = 0;
     Ivar *ivarList = class_copyIvarList(class, &ivarCount);
     Ivar *ivarList = class_copyIvarList(class, &ivarCount);
@@ -313,10 +403,11 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     return boxedIvars;
     return boxedIvars;
 }
 }
 
 
+/// Skips NSObject
 + (NSArray<FLEXIvarBox *> *)inheritedIvarsForClass:(Class)class
 + (NSArray<FLEXIvarBox *> *)inheritedIvarsForClass:(Class)class
 {
 {
     NSMutableArray<FLEXIvarBox *> *inheritedIvars = [NSMutableArray array];
     NSMutableArray<FLEXIvarBox *> *inheritedIvars = [NSMutableArray array];
-    while ((class = [class superclass])) {
+    while ((class = [class superclass]) && class != [NSObject class]) {
         [inheritedIvars addObjectsFromArray:[self ivarsForClass:class]];
         [inheritedIvars addObjectsFromArray:[self ivarsForClass:class]];
     }
     }
     return inheritedIvars;
     return inheritedIvars;
@@ -324,10 +415,7 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 
 
 - (void)updateFilteredIvars
 - (void)updateFilteredIvars
 {
 {
-    NSArray<FLEXIvarBox *> *candidateIvars = self.ivars;
-    if (self.includeInheritance) {
-        candidateIvars = [candidateIvars arrayByAddingObjectsFromArray:self.inheritedIvars];
-    }
+    NSArray<FLEXIvarBox *> *candidateIvars = [self metadata:FLEXMetadataKindIvars forScope:self.scope];
     
     
     NSArray<FLEXIvarBox *> *unsortedFilteredIvars = nil;
     NSArray<FLEXIvarBox *> *unsortedFilteredIvars = nil;
     if ([self.filterText length] > 0) {
     if ([self.filterText length] > 0) {
@@ -373,12 +461,15 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
 {
 {
     Class class = [self.object class];
     Class class = [self.object class];
     self.methods = [[self class] methodsForClass:class];
     self.methods = [[self class] methodsForClass:class];
-    self.inheritedMethods = [[self class] inheritedMethodsForClass:class];
+    self.methodsWithParent = [self.methods arrayByAddingObjectsFromArray:[[self class] methodsForClass:[class superclass]]];
+    self.inheritedMethods = [self.methods arrayByAddingObjectsFromArray:[[self class] inheritedMethodsForClass:class]];
+    self.NSObjectMethods = [[self class] methodsForClass:[NSObject class]];
 }
 }
 
 
 - (void)updateFilteredMethods
 - (void)updateFilteredMethods
 {
 {
-    self.filteredMethods = [self filteredMethodsFromMethods:self.methods inheritedMethods:self.inheritedMethods areClassMethods:NO];
+    NSArray<FLEXMethodBox *> *candidateMethods = [self metadata:FLEXMetadataKindMethods forScope:self.scope];
+    self.filteredMethods = [self filteredMethodsFromMethods:candidateMethods areClassMethods:NO];
 }
 }
 
 
 - (void)updateClassMethods
 - (void)updateClassMethods
@@ -386,16 +477,23 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     const char *className = [NSStringFromClass([self.object class]) UTF8String];
     const char *className = [NSStringFromClass([self.object class]) UTF8String];
     Class metaClass = objc_getMetaClass(className);
     Class metaClass = objc_getMetaClass(className);
     self.classMethods = [[self class] methodsForClass:metaClass];
     self.classMethods = [[self class] methodsForClass:metaClass];
-    self.inheritedClassMethods = [[self class] inheritedMethodsForClass:metaClass];
+    self.classMethodsWithParent = [self.classMethods arrayByAddingObjectsFromArray:[[self class] methodsForClass:[metaClass superclass]]];
+    self.inheritedClassMethods = [self.classMethods arrayByAddingObjectsFromArray:[[self class] inheritedMethodsForClass:metaClass]];
+    self.NSObjectClassMethods = [[self class] methodsForClass:[NSObject class]];
 }
 }
 
 
 - (void)updateFilteredClassMethods
 - (void)updateFilteredClassMethods
 {
 {
-    self.filteredClassMethods = [self filteredMethodsFromMethods:self.classMethods inheritedMethods:self.inheritedClassMethods areClassMethods:YES];
+    NSArray<FLEXMethodBox *> *candidateMethods = [self metadata:FLEXMetadataKindClassMethods forScope:self.scope];
+    self.filteredClassMethods = [self filteredMethodsFromMethods:candidateMethods areClassMethods:YES];
 }
 }
 
 
 + (NSArray<FLEXMethodBox *> *)methodsForClass:(Class)class
 + (NSArray<FLEXMethodBox *> *)methodsForClass:(Class)class
 {
 {
+    if (!class) {
+        return @[];
+    }
+    
     NSMutableArray<FLEXMethodBox *> *boxedMethods = [NSMutableArray array];
     NSMutableArray<FLEXMethodBox *> *boxedMethods = [NSMutableArray array];
     unsigned int methodCount = 0;
     unsigned int methodCount = 0;
     Method *methodList = class_copyMethodList(class, &methodCount);
     Method *methodList = class_copyMethodList(class, &methodCount);
@@ -410,22 +508,19 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
     return boxedMethods;
     return boxedMethods;
 }
 }
 
 
+/// Skips NSObject
 + (NSArray<FLEXMethodBox *> *)inheritedMethodsForClass:(Class)class
 + (NSArray<FLEXMethodBox *> *)inheritedMethodsForClass:(Class)class
 {
 {
     NSMutableArray<FLEXMethodBox *> *inheritedMethods = [NSMutableArray array];
     NSMutableArray<FLEXMethodBox *> *inheritedMethods = [NSMutableArray array];
-    while ((class = [class superclass])) {
+    while ((class = [class superclass]) && class != [NSObject class]) {
         [inheritedMethods addObjectsFromArray:[self methodsForClass:class]];
         [inheritedMethods addObjectsFromArray:[self methodsForClass:class]];
     }
     }
     return inheritedMethods;
     return inheritedMethods;
 }
 }
 
 
-- (NSArray<FLEXMethodBox *> *)filteredMethodsFromMethods:(NSArray<FLEXMethodBox *> *)methods inheritedMethods:(NSArray<FLEXMethodBox *> *)inheritedMethods areClassMethods:(BOOL)areClassMethods
+- (NSArray<FLEXMethodBox *> *)filteredMethodsFromMethods:(NSArray<FLEXMethodBox *> *)methods areClassMethods:(BOOL)areClassMethods
 {
 {
     NSArray<FLEXMethodBox *> *candidateMethods = methods;
     NSArray<FLEXMethodBox *> *candidateMethods = methods;
-    if (self.includeInheritance) {
-        candidateMethods = [candidateMethods arrayByAddingObjectsFromArray:inheritedMethods];
-    }
-    
     NSArray<FLEXMethodBox *> *unsortedFilteredMethods = nil;
     NSArray<FLEXMethodBox *> *unsortedFilteredMethods = nil;
     if ([self.filterText length] > 0) {
     if ([self.filterText length] > 0) {
         NSMutableArray<FLEXMethodBox *> *mutableUnsortedFilteredMethods = [NSMutableArray array];
         NSMutableArray<FLEXMethodBox *> *mutableUnsortedFilteredMethods = [NSMutableArray array];
@@ -736,34 +831,22 @@ static const NSInteger kFLEXObjectExplorerScopeIncludeInheritanceIndex = 1;
         } break;
         } break;
             
             
         case FLEXObjectExplorerSectionProperties: {
         case FLEXObjectExplorerSectionProperties: {
-            NSUInteger totalCount = [self.properties count];
-            if (self.includeInheritance) {
-                totalCount += [self.inheritedProperties count];
-            }
+            NSUInteger totalCount = [self totalCountOfMetadata:FLEXMetadataKindProperties forScope:self.scope];
             title = [self sectionTitleWithBaseName:@"Properties" totalCount:totalCount filteredCount:[self.filteredProperties count]];
             title = [self sectionTitleWithBaseName:@"Properties" totalCount:totalCount filteredCount:[self.filteredProperties count]];
         } break;
         } break;
             
             
         case FLEXObjectExplorerSectionIvars: {
         case FLEXObjectExplorerSectionIvars: {
-            NSUInteger totalCount = [self.ivars count];
-            if (self.includeInheritance) {
-                totalCount += [self.inheritedIvars count];
-            }
+            NSUInteger totalCount = [self totalCountOfMetadata:FLEXMetadataKindIvars forScope:self.scope];
             title = [self sectionTitleWithBaseName:@"Ivars" totalCount:totalCount filteredCount:[self.filteredIvars count]];
             title = [self sectionTitleWithBaseName:@"Ivars" totalCount:totalCount filteredCount:[self.filteredIvars count]];
         } break;
         } break;
             
             
         case FLEXObjectExplorerSectionMethods: {
         case FLEXObjectExplorerSectionMethods: {
-            NSUInteger totalCount = [self.methods count];
-            if (self.includeInheritance) {
-                totalCount += [self.inheritedMethods count];
-            }
+            NSUInteger totalCount = [self totalCountOfMetadata:FLEXMetadataKindMethods forScope:self.scope];
             title = [self sectionTitleWithBaseName:@"Methods" totalCount:totalCount filteredCount:[self.filteredMethods count]];
             title = [self sectionTitleWithBaseName:@"Methods" totalCount:totalCount filteredCount:[self.filteredMethods count]];
         } break;
         } break;
             
             
         case FLEXObjectExplorerSectionClassMethods: {
         case FLEXObjectExplorerSectionClassMethods: {
-            NSUInteger totalCount = [self.classMethods count];
-            if (self.includeInheritance) {
-                totalCount += [self.inheritedClassMethods count];
-            }
+            NSUInteger totalCount = [self totalCountOfMetadata:FLEXMetadataKindClassMethods forScope:self.scope];
             title = [self sectionTitleWithBaseName:@"Class Methods" totalCount:totalCount filteredCount:[self.filteredClassMethods count]];
             title = [self sectionTitleWithBaseName:@"Class Methods" totalCount:totalCount filteredCount:[self.filteredClassMethods count]];
         } break;
         } break;