Adding a category to NSObject which can dynamically provide an array
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Tue, 26 Oct 2004 23:18:13 +0000 (23:18 +0000)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Tue, 26 Oct 2004 23:18:13 +0000 (23:18 +0000)
of any class' subclasses (and direct subclasses, meaning only those
classes whose parent is the class to which the message was sent) via
two new class methods, +subclasses, and +directSubclasses.

ITCategory-NSObject.h [new file with mode: 0644]
ITCategory-NSObject.m [new file with mode: 0644]
ITFoundation.xcode/project.pbxproj

diff --git a/ITCategory-NSObject.h b/ITCategory-NSObject.h
new file mode 100644 (file)
index 0000000..96c7e31
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *     ITKit
+ *  ITCategory-NSObject.h
+ *    Category which extends NSObject
+ *
+ *  Original Author : Joseph Spiros <joseph.spiros@ithinksw.com>
+ *   Responsibility : Joseph Spiros <joseph.spiros@ithinksw.com>
+ *
+ *  Copyright (c) 2002 - 2004 iThink Software.
+ *  All Rights Reserved
+ *
+ */
+
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface NSObject (ITCategory)
+
++ (NSArray *)subclasses;
++ (NSArray *)directSubclasses;
+
+
+@end
diff --git a/ITCategory-NSObject.m b/ITCategory-NSObject.m
new file mode 100644 (file)
index 0000000..09281e8
--- /dev/null
@@ -0,0 +1,129 @@
+#import "ITCategory-NSObject.h"
+#import <objc/objc-runtime.h>
+
+@implementation NSObject (ITCategory)
+
++ (NSArray *)subclasses
+{
+    NSMutableArray    *tempArray;
+    NSArray           *resultArray;
+    Class             *classes;
+    struct objc_class *superClass;
+    Class             *current;
+    int                count, newCount, index;
+
+    tempArray   = [[NSMutableArray allocWithZone:nil] initWithCapacity:12];
+    resultArray = nil;
+
+    if (tempArray)
+    {
+        classes = NULL;
+        count   = objc_getClassList(NULL, 0);
+        if (count)
+        {
+            classes = malloc(sizeof(Class) * count);
+            if (classes)
+            {
+                newCount = objc_getClassList(classes, count);
+                while (count < newCount)
+                {
+                    count = newCount;
+                    free(classes);
+                    classes = malloc(sizeof(Class) * count);
+                    if (classes)
+                        newCount = objc_getClassList(classes, count);
+                }
+                count = newCount;
+            }
+        }
+
+        if (classes)
+        {
+            const Class thisClass = [self class];
+            current = classes;
+
+            for (index = 0; index < count; ++index)
+            {
+                superClass = (*current)->super_class;
+                if (superClass)
+                {
+                    do
+                    {
+                        if (superClass == thisClass)
+                        {
+                            [tempArray addObject:*current];
+                            break;
+                        }
+                        superClass = superClass->super_class;
+                    } while (superClass);
+                }
+
+                ++current;
+            }
+
+            free(classes);
+        }
+
+        resultArray = [NSArray arrayWithArray:tempArray];
+        [tempArray release];
+    }
+
+    return resultArray;
+}
+
++ (NSArray *)directSubclasses
+{
+    NSMutableArray *tempArray;
+    NSArray        *resultArray;
+    Class          *classes;
+    Class          *current;
+    int             count, newCount, index;
+
+    tempArray   = [[NSMutableArray allocWithZone:nil] initWithCapacity:12];
+    resultArray = nil;
+
+    if (tempArray)
+    {
+        classes = NULL;
+        count   = objc_getClassList(NULL, 0);
+        if (count)
+        {
+            classes = malloc(sizeof(Class) * count);
+            if (classes)
+            {
+                newCount = objc_getClassList(classes, count);
+                while (count < newCount)
+                {
+                    count = newCount;
+                    free(classes);
+                    classes = malloc(sizeof(Class) * count);
+                    if (classes)
+                        newCount = objc_getClassList(classes, count);
+                }
+                count = newCount;
+            }
+        }
+
+        if (classes)
+        {
+            const Class thisClass = [self class];
+            current = classes;
+
+            for (index = 0; index < count; ++index)
+            {
+                if ((*current)->super_class == thisClass)
+                    [tempArray addObject:*current];
+                ++current;
+            }
+
+            free(classes);
+        }
+
+        resultArray = [NSArray arrayWithArray:tempArray];
+        [tempArray release];
+    }
+
+    return resultArray;
+}
+
+@end
\ No newline at end of file
index 0ea001c..e7e51ca 100755 (executable)
 //2A4
                2AB93A2C057059DC007E748F = {
                        children = (
+                               7C058DF7072F10530082E1E9,
+                               7C058DF8072F10530082E1E9,
                                2AB93A3005705A0C007E748F,
                                2AB93A3105705A0C007E748F,
                        );
 //7C2
 //7C3
 //7C4
+               7C058DF7072F10530082E1E9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = "ITCategory-NSObject.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               7C058DF8072F10530082E1E9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = "ITCategory-NSObject.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               7C058DF9072F10530082E1E9 = {
+                       fileRef = 7C058DF7072F10530082E1E9;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               7C058DFA072F10530082E1E9 = {
+                       fileRef = 7C058DF8072F10530082E1E9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                7C97DC2C05B614300013E85F = {
                        fileEncoding = 4;
                        isa = PBXFileReference;
                                3D97137F05D9FBF40033607F,
                                3D97138A05D9FD6B0033607F,
                                376AF4DF06597CA900F0979E,
+                               7C058DF9072F10530082E1E9,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                3D97138105D9FBFA0033607F,
                                3D97138B05D9FD6B0033607F,
                                376AF4E006597CA900F0979E,
+                               7C058DFA072F10530082E1E9,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;