Latest 1.0.1
Homepage https://github.com/xareelee/XObjCUnderhood
License MIT
Platforms ios 7.0, osx 10.9, requires ARC
Authors

XObjCUnderhood is a library which utilizes the Obj-C runtime to understand the Obj-C class hierarchy, methods, and protocols in the runtime. It’s useful to study a framework or a third-party library.

For example, you could discover all subclasses of UIButton:

xobjc_logSubclassesForClass("UIButton");
// Output
* UIButton
  * CNPropertyLabelButton
  * CNQuickActionButton
  * CNTransportButton
    * ABTransportButton
    * CNStarkKnobTransportButton
  * MKButtonWithTargetArgument
  * UIAlertButton
  ...

or find all classes (and their subclasses) which adopt the protocol UITableViewDataSource:

xobjc_logAllClassesForProtocol("UITableViewDataSource");
* ABAccountsAndGroupDataSource: {}
* ABCardPropertyPicker: {}
* ABItemLabelPicker: {}
* ABMembersDataSource: {}
* ABMembersFilteredDataSource: {}
...

For more information, please refer to the section "Very useful XObjCUnderhood functions".

How to use

(1) Installation via CocoaPods

XObjCUnderhood is designed for studying Obj-C classes in development, not in production. You should only include XObjCUnderhood in the Debug mode.

You could install XObjCUnderhood by CocoaPods:

pod 'XObjCUnderhood', '~> 1.0', :configurations => ['Debug']

If you need to install XObjCUnderhood manually, you should include all files in the XObjCUnderhood directory and also M13OrderedDictionary library.

It’s also highly recommended to install my another library — ObjCJSONLikeDescription and its subspec for M13OrderedDictionary to make the descriptions of collection objects be more JSON-like.

pod 'ObjCJSONLikeDescription', :configurations => ['Debug']
pod 'ObjCJSONLikeDescription/M13OrderedDictionary', :configurations => ['Debug']

(2) XObjCUnderhood setup

You should set up XObjCUnderhood library in either application:didFinishLaunchingWithOptions: or lldb/gdb before using any XObjCUnderhood functions:

xobjc_underhood_setup();
// or in lldb/gdb
(lldb) po xobjc_underhood_setup()

This setup will analyze and build up the inheritance hierarchy for all Objective-C classes and protocols at the runtime.

(3) Start using XObjCUnderhood

For the sake of convenience, it’s recommended to use XObjCUnderhood library in the lldb/gdb by a runtime break.

// print all classes (keys) and their subclasses (values), respectively.
(lldb) po xobjc_classHierarchyLookUp()

You could find many useful functions in the XObjCUnderhoodBasics.h or XObjCUnderhoodOverloadables.h. XObjCUnderhood use C11 overloadable to make those functions take either a class/protocol type or a class/protocol name.

// pass a protocol object
xobjc_logAllClassesForProtocol(@protocol(UITableViewDataSource));
// or a protocol name
xobjc_logAllClassesForProtocol("UITableViewDataSource");

In lldb/gdb, it’s recommended to pass a string value as the parameter to XObjCUnderhood functions, because Objective-C directives like @protocol may not be resolved correctly in the lldb/gdb.

Very useful XObjCUnderhood functions

Hint: you could use shortcut ⌘ + k to clear Xcode console whenever you want.

Note: you should set up XObjCUnderhood library first by calling xobjc_underhood_setup().

** print all classes and their subclasses

(lldb) po xobjc_classHierarchyLookUp()

You can use this function to get the whole class list in the runtime. Try to search a class name in the Xcode console, you should get two search results — one for their subclasses and one for its superclass.

Note: The objects for the key $root_classes are the Objective-C root classes.

** print all subclasses for a class

(lldb) po xobjc_subclassesOfClass("UIButton")
// or
(lldb) po xobjc_subclassesOfClass([UIButton class])

This is very useful if you want to know all subclasses (concrete classes) for a class. It makes you learn how to use a library quickly due to Liskov substitution principle (LSP).

Liskov substitution principle: “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” — Wikipedia

** print all classes conforming a protocol

(lldb) po xobjc_allClassesForProtocol("UITableViewDataSource")

This function is very using if you encounter a method like this:

- (void)bindDataSource:(id<UITableViewDataSource>)dataSource;

You could pass any instance object conforming the protocol to the method.

** print all implemented interfaces in a class

(lldb) po xobjc_implementedInterfaceForClass("UIView")

Disclose the implemented interfaces in a class, including private methods/properties.

** print all implemented interfaces through the class hierarchy

(lldb) po xobjc_logMethodListForClass("UIView")  // to the root class
(lldb) po xobjc_logMethodListForClass("UIView", "UIResponder")

Print all interfaces through the class hierarchy.

About

Author

License

XAspect is available under the MIT license. See the LICENSE file for more info.

Latest podspec

{
    "name": "XObjCUnderhood",
    "version": "1.0.1",
    "license": "MIT",
    "summary": "Disclose the Objective-C classes/interfaces under the hood",
    "homepage": "https://github.com/xareelee/XObjCUnderhood",
    "authors": {
        "Kang-Yu Xaree Lee": "[email protected]"
    },
    "source": {
        "git": "https://github.com/xareelee/XObjCUnderhood.git",
        "tag": "1.0.1",
        "submodules": true
    },
    "requires_arc": true,
    "platforms": {
        "ios": "7.0",
        "osx": "10.9"
    },
    "default_subspecs": "Core",
    "subspecs": [
        {
            "name": "Core",
            "public_header_files": "XObjCUnderhood/Core/*.h",
            "source_files": "XObjCUnderhood/Core/*.{h,m}",
            "frameworks": "Foundation",
            "dependencies": {
                "M13OrderedDictionary": []
            }
        }
    ]
}

Pin It on Pinterest

Share This