Using Objective-C Metadata to Generate Class Dependency Graph - objective-c

This guy came up with a pretty neat tool to generate a class dependency graph - however, it relies on parsing your source code and looking for #import directives.
http://seriot.ch/blog.php?article=20110124
https://github.com/nst/objc_dep/blob/master/objc-dep.py
This is neat, but I have a number of problems with this. Not least of which is it doesn't take into account imports of imports nor prefix headers nor whether-or-not the class(es) in the file referenced by the import are actually being used.
I'd like to do something more akin to class-dump and examine the Objective-C metadata stored in the Mach-O file to generate an in-memory representation of the class dependencies.
I'd rather not do this from scratch, so I'm wondering:
Has it already been done?
Is there an open-source library which would provide me with the foundational tools I need to extract this information (a library which examines the Mach-O file and creates a façade of the Objective-C information contained within - such that I could iterate over all of the classes, their methods, properties, ivars, etc and scan for references to other classes) I figure class-dump's source would be a good place to start.
If you have experience in this sort of thing, is what I'm trying to accomplish feasible?
What roadblocks will I need to overcome?

Has it already been done?
Not that I know of.
Is there an open-source library which would provide me with the
foundational tools I need to extract this information?
At the core of class-dump is libMachObjC which does exatly what you want, i.e. parse all classes/methods/ivars and more. The API is very clean, it should be very easy to use.
If you have experience in this sort of thing, is what I'm trying to
accomplish feasible?
Unfortunately, no because some classes don't declare the real class but use id instead. For example, here is the information that can be extracted from a class-dump of UIKit:
#interface UITableView : UIScrollView <NSCoding>
{
int _style;
id <UITableViewDataSource> _dataSource;
id _rowData;
...
The _rowData ivar type information is id but if you check at runtime you will see that _rowData is an instance of the UITableViewRowData class. This information is not present in the Mach-O binary so you have no way to find the relation between UITableView and UITableViewRowData. The same applies for method parameters.

Here's a solution that relies on information in mach.o files, and generates graph dependency based on that information: https://github.com/PaulTaykalo/objc-dependency-visualizer

Has it already been done?
yes - but i can't recommend a good public implementation
Is there an open-source library which would provide me with the foundational tools I need to extract this information (a library which examines the Mach-O file and creates a façade of the Objective-C information contained within - such that I could iterate over all of the classes, their methods, properties, ivars, etc and scan for references to other classes) I figure class-dump's source would be a good place to start.
most use cases would benefit by using the objc runtime facilities objc/... rather than examining the binary.
If you have experience in this sort of thing, is what I'm trying to accomplish feasible?
yes. i've done something similar using the objc runtime.
What roadblocks will I need to overcome?
that depends largely on the level of detail you want... implementation time if you find no such implementation, but i figure you will find a few options if you google the more esoteric functions in the objc runtime; perhaps you would find one in an (open) language binding or bridge?
if you do end up writing one yourself, you can get registered objc classes using objc_getClassList, then access the properties/information you want from there.

Related

ClassImp preprocessor macro in ROOT - Is it really needed?

Do I really have to use the ClassImp macro to benefit the automatic dictionary and streamer generation in ROOT? Some online tutorials and examples mention it but I noticed that simply adding the ClassDef(MyClass, <ver>) macro to MyClass.h and processing it with rootcint/rootcling already generates most of such code.
I did look at Rtypes.h where these macros are defined but to follow preprocessor macros calling each other is not easy and so, it would be nice if experts could confirm the role of ClassImp. I am specifically interested in recent versions of ROOT >= 5.34
Here is the answer I got on roottalk mailing list confirming that the usage of ClassImp is essentially outdated.
ClassImp is used to register in the TClass the name of the source file
for the class. This was used in particular by THtml (which has now
been deprecated in favor of Doxygen). So unless you code/framework
needs to know the name of the source files, it is no longer necessary
to have ClassImp.
ClassDef is necessary for class inheriting from TObject (or from any
classes that has a ClassDef). In the other cases, it provide
accelerator that makes the I/O slightly faster (and thus is
technically not compulsory in this case). It also assign a version
number to the schema layout which simplifies writing schema evolution
rules (on the other hand, there is other alternative to assign a
version number to the schema layout).
What exactly are you trying to do? The ClassImp and ClassDef macros add members to the class that provide Run-Time Type Information and allow the class to be written to root files. If you are not interested in that, then don't bother with these macros.
I never use them.

Header files without implementation

I'm working on a open source project, which consist on a framework for iOS devices, and one of the methods is not working as I expected. I tried to search for the implementation of the method, but all I found was a a header file and the method declaration; I didn't find the implementation anywhere. Neither did I find the .m file corresponding to that class.
So I have some questions:
How can a class exist without it's implementation and still its methods perform certain operations?
What is the purpose of writing this kind of classes.
In this kind of situations where should be the methods implemented?
Note
The open source project is FastPdfKit and the method is wholeTextForPage:
Well, those methods are somewhere, so it's not that they don't exist, you just can't see them.
Try for example to open UITableView.h, you can see the methods definition, but not the implementation. The implementation is hidden in the library, but you can't see it.
In a nutshell, developers do this to hide the details of the implementation of a class to other users. You just receive a header that tells you which methods you can use, and how, but the details about how are they implemented are hidden for you.
For example, Apple doesn't want you to see how they implemented UITableView, but they want you to know how you can use it.
Here you can find a tutorial about how to create a library for Objective-C:
Creating Static Libraries for Objective-C

Categories provide dynamic loading?

I am looking at this page about C++ differences from Objective C and it states this:
The dynamic nature of Objective C allows existing classes to be extended at runtime. Objective C allows you to define categories, related sets of extensions to objects you've already created. For example, in converting a text-based app into a graphics app, the code your objects needed to draw themselves could be compiled as a category and loaded at run-time only when needed. This saves memory and allows you to leave your original objects unmodified.
Now I am familiar with Categories and have used them, but I do not see how they lead to dynamic loading. If you import a Category file, is it not compiled along with the class it extends, taking up memory whenever you use that class, whether you use the Category methods or not?
You can load a bundle/plugin/framework at runtime. This is the dynamic nature of Objective-c that the quote references. It is not specific to Categories.
However, if the (compiled) code you load includes a Category on an existing Class, the extensions will work just as if they had been there all along. Ie a Class is not 'Frozen' at compile time, and loading a bundle/plugin/framework is one way to add new methods to an existing class at runtime.
This makes it relatively easy to implement a plugin architecture, or load code only when needed to make app startup time faster/keep memory footprint down, compared to some other C based compiled languages.
If you link with a static library containing a category, the linker will copy all of the category code into your executable file. If you link with a shared library, the shared library's entire code segment gets mapped into your process's address space, but it's paged in lazily, so you might not actually read all of the category code off of the disk unless you use it all.
But I think that's not really what the page is talking about.
Link-time libraries
First, let's talk about libraries that you tell the linker to link your app with.
Consider NSString. The NSString class is defined in the Foundation framework, which is a framework full of general-purpose classes useful in programs that have GUIs and in programs that don't have GUIs. So the NSString class as defined in Foundation doesn't include any code for drawing a string into a graphics context, because that code would (usually) be useless in a non-GUI app.
The AppKit framework (on OS X) manages a GUI. It's useful in a GUI to be able to draw strings to a graphics context, so AppKit contains a category on NSString that adds methods for drawing a string, like drawAtPoint:withAttributes:. UIKit (on iOS) does the same thing (but the methods are a little bit different).
So if you write a program on the OS X and use Foundation but don't use AppKit, your process won't load the AppKit NSString category and you won't pay the price for all of those graphics methods on NSString.
For a shared library like AppKit, the price is pretty trivial on modern hardware.
Now, you could do the same thing with your own libraries, which you might make static. Let's say you make a “TwitterModel” library for talking to Twitter. It's full of classes that model the things you find on Twitter, like accounts and tweets. But you don't include code for managing a GUI to display tweets.
Instead, you make another library, “TwitterGUI”, that (in addition to defining yet more classes) uses categories to add methods to the model classes in your “TwitterModel” library.
If you write a program that links to both TwitterGUI and TwitterModel, the executable file will contain all of the Objective-C code from both libraries. But if you write a command-line only program (no GUI) and only link it with TwitterModel, that program won't contain any of the GUI-related code. Oh, the savings!
Run-time libraries
Now let's consider shared libraries that you don't tell the linker to link your app with.
You can dynamically load new code into your process at runtime, using an API like dlopen or -[NSBundle load]. If the library contains categories, those categories will be added to the classes in your running program.
So, you could make your app optionally use a shared library if it exists on the user's system when he runs your app, by trying to load the library programmatically. If you succeed, you can call any category methods that you know the library defines. (And of course you can use the classes that the library provides, if any.) If you fail to load the library, you carefully avoid calling any of those category methods from the library.
Typically, though, we use a dynamic loading API to load a plugin, and the plugin provides some class that subclasses a base class, or conforms to a protocol, that we've defined specifically for plugins to implement. We just need to get the name of that class, and then we create an instance of it and send it the messages that we defined in our base class or protocol.

Objective-C equivalent of Java packages?

What is the Objective-C equivalent of Java packages? How do you group and organize your classes in Objective-C?
Question 1: Objective-C equivalent of Java packages?
Objective-C doesn't have an equivalent to Java packages or C++ namespaces. Part of the reason for this is that Objective-C was originally a very thin runtime layer on top of C, and added objects to C with minimum fuss. Unfortunately for us now, naming conflicts are something we have to deal with when using Objective-C. You win some, you lose some...
One small clarification (although it's not much for consolation) is that Objective-C actually has two flat namespaces — one for classes and one for protocols (like Java's interfaces). This doesn't solve any class naming conflicts, but it does mean you can have a protocol and class with the same name (like <NSObject> and NSObject) where the latter usually adopts ("implements") the former. This feature can prevent "Foo / FooImpl" pattern rampant in Java, but sadly doesn't help with class conflicts.
Question 2: How to [name] and organize Objective-C classes?
Naming
The following rules are subjective, but they are decent guidelines for naming Objective-C classes.
If your code can't be run by other code (it's not a framework, plugin, etc. but an end-user application or tool) you only need to avoid conflicts with code you link against. Often, this means you can get away with no prefix at all, so long as the frameworks/plugins/bundles you use have proper namespaces.
If you're developing "componentized" code (like a framework, plugin, etc.) you should choose a prefix (hopefully one that's unique) and document your use of it someplace visible so others know to avoid potential conflicts. For example, the CocoaDev wiki "registry" is a de facto public forum for calling "dibs" on a prefix. However, if your code is something like a company-internal framework, you may be able to use a prefix that someone else already does, so long as you aren't using anything with that prefix.
Organization
Organizing source files on disk is something that many Cocoa developers unfortunately gloss over. When you create a new file in Xcode, the default location is the project directory, right beside your project file, etc. Personally, I put application source in source/, test code (OCUnit, etc.) in test/, all the resources (NIB/XIB files, Info.plist, images, etc.) in resources/, and so on. If you're developing a complex project, grouping source code in a hierarchy of directories based on functionality can be a good solution, too. In any case, a well-organized project directory makes it easier to find what you need.
Xcode really doesn't care where your files are located. The organization in the project sidebar is completely independent of disk location — it is a logical (not physical) grouping. You can organize however you like in the sidebar without affecting disk location, which is nice when your source is stored in version control. On the other hand, if you move the files around on disk, patching up Xcode references is manual and tedious, but can be done. It's easiest to create your organization from the get-go, and create files in the directory where they belong.
My Opinion
Although it could be nice to have a package/namespace mechanism, don't hold your breath for it to happen. Class conflicts are quite rare in practice, and are generally glaringly obvious when they happen. Namespaces are really a solution for a non-problem in Objective-C. (In addition, adding namespaces would obviate the need for workarounds like prefixes, but could introduce a lot more complexity in method invocation, etc.)
The more subtle and devious bugs come from method conflicts when methods are added and/or overridden, not only by subclasses, but also be categories, which can cause nasty errors, since the load order of categories is undefined (nondeterministic). Implementing categories is one of the sharpest edges of Objective-C, and should only be attempted if you know what you're doing, particularly for third-party code, and especially for Cocoa framework classes.
They use long names...
Article on coding style & naming in Cocoa / Objective-C
Discussion whether Obj-C needs namespaces (deleted, archive here)
See
What is the best way to solve an Objective-C namespace collision?
for a discussion of how Objective-C has no namespaces, and the painful hacks this necessitates.
Unfortuantely objective c doesn't have any equivalent to namespace of C#,c++ and package of java....
The naming collisions could be solved by giving contextual name for example if u gonna give a name to method it should imply the class and module that it comes in so that...these problems could be avoided.
Go through the following url to know more on naming convention as advised by apple
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
What about something like this (inside a directory)?
#define PruebaPaquete ar_com_oxenstudio_paq1_PruebaPaquete
#interface ar_com_oxenstudio_paq1_PruebaPaquete : NSObject {
and importing it like this:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
PruebaPaquete *p = [[PruebaPaquete alloc] init];
and when you have name collision:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
#import "ar/com/oxenstudio/paq2/PruebaPaquete.h"
ar_com_oxenstudio_paq1_PruebaPaquete *p = [[ar_com_oxenstudio_paq1_PruebaPaquete alloc] init];
ar_com_oxenstudio_paq2_PruebaPaquete *p2 = [[ar_com_oxenstudio_paq2_PruebaPaquete alloc] init];
Well, I think all the other answers here seem to focus on naming collisions, but missed at least one important feature, package private access control that java package provides.
When I design a class, I find it is quite often that I just want some specific class(es) to call its methods, b/c they work together to achieve a task, but I don't want all the other unrelated classes to call those methods. That is where java package access control comes in handy, so I can group the related classes into a packaged and make those methods package private access control. But there is no way to do that in objective c.
Without package private access control I find it is very hard to avoid people writing code like this, [[[[[a m1] m2] m3] m4] m5] or [a.b.c.d m1].
Update: Xcode 4.4 introduced "An Objective-C class extension header", in my opinion, that is in some way to provide "package private access control", so if you include the extension header, you can call my "package private" methods; if you only include my public header, you can only call my public API.

Is the Objective-C Runtime API Available outside Darwin?

Objective-C has an amazing API for reading and changing its own runtime environment, but I can only find documentation for this API from Apple. Is the API only available on machines running a Darwin OS or is it actually part of Objective-C in general?
If its specific to Darwin is it at least available in the GNUstep framework?
Edit - What I'm Looking for Specifically
Specifically I am writing an XSD based serializer/deserializer and I would like to be able to create/modify class definitions based on XSD documents that are parsed during runtime, in order to make the framework more intuitive.
All the versions of Objective-C that I've seen have some facilities for mucking about with introspection and/or dynamic generation of classes at runtime.
The details will be different per different runtime and they may not all have feature parity (example; the apple runtime has blocks and that hasn't been ported everywhere).
Your updated question indicates you specifically wish to add/modify class definitions.
Following the reference Objective-C Compiler and Runtime FAQ mentioned above in the comments we find about libobjc2 which is part of GUNStep, and it’s runtime.h contains the method:
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes);
for creating classes - this appears to be the same as the one in Cocoa.
You might find Mike Ash's Creating Classes at Runtime in Objective-C helpful.
HTH