fill the void - bdunagan

17 May 2010
class-dump: Dumping Classes

class-dump path_to_executable

If the tool nm and its wealth of information seems impressive, class-dump is amazing. Feed it an executable and get back a complete list of class names, internal variables, and methods, even as a set of header files, thanks to its deep understanding of Objective-C and Mach-O. Apple’s product might be stripped of their symbols, but class-dump can list their internal structure.

I created a template application, added a method (shouldShowInClassDump), and built it with all the symbols stripped out. Running class-dump on the resulting Release executable revealed the following:

* Generated by class-dump 3.3.1 (64 bit).
* class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2009 by Steve Nygard.

#pragma mark -

* File: build/Release/
* Arch: Intel x86-64 (x86_64)
* Objective-C Garbage Collection: Unsupported

@interface SampleAppAppDelegate : NSObject
NSWindow *window;

- (void)applicationDidFinishLaunching:(id)arg1;
- (BOOL)shouldShowInClassDump:(id)arg1;
@property NSWindow *window; // @synthesize window;


To see how applications compared in aggregate, I wrote a simple ruby script to walk through /Applications and sum up the number of lines of headers from class-dump and the number of @interface declarations. Both are crude measures of complexity.

Top 10 by Header Lines

37968	iPhoto
37053 Aperture
21228 iWeb
19307 Keynote
16564 iMovie
16235 Coda
15625 Keynote
15111 Grapher
14735 Pages
14724 iCal

Top 10 by Interfaces

1203	Aperture
1066 iWeb
1004 Grapher
967 iPhoto
859 Path Finder
748 Keynote
730 iMovie
664 LaunchBar
649 iCal
646 Coda

Top 10 by Lines Per Interface

39.54	Retrospect
39.33 Grab
39.26 iPhoto
37.72 MemoryMiner
37.28 Papers
35.72 iTunes
35.65 Sequel Pro
34.71 Console
32.72 iChat
32.38 GarageBand

Apple’s tools are clearly complex, with iPhoto and Aperture leading by almost a factor of two in header lines, but apps like Panic’s Coda hold their own. And Retrospect topping the final list is obviously an indictment of my coding abilities.

Ruby Script


# analyze_apps.rb
# * Analyze dump from 'class-dump path_to_executable' to collect statistics: Interfaces, Lines

# Collect app paths.
CLASS_DUMP_PATH = "/usr/local/bin/class-dump"
apps = []
apps_folders = ["/Applications", "/Applications/iWork '08", "/Applications/iWork '09", "/Applications/Microsoft Office 2004", "/Applications/Microsoft Office 2008", "/Applications/Utilities"]
apps_folders.each do |app_folder|
app_list = Dir.entries(app_folder)
app_list.each do |app|
apps << "#{app_folder}/#{app}"

# Loop through apps.
apps.each do |app|
# Check that the app exists.
if Dir.exists?("#{app}") && app.include?(".app")
app_array = app.split("/")
app_name = app_array[app_array.count-1].split(".app")[0]
exe_path = "#{app}/Contents/MacOS/#{app_name}"
# Check that the executable exists.
if File.exists?(exe_path)
# Use 'classdump' to dump Mach-O header information.
results = %x[#{CLASS_DUMP_PATH} "#{exe_path}"].split("\n")
line_count = results.count
interface_count = 0
results.each do |line|
if line.include?("@interface ")
interface_count = interface_count + 1
# puts "#{app_name}: #{line}"
puts "#{app_name},#{app},#{interface_count},#{line_count}"
Previous LinkedIn Twitter GitHub Email Next