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
Related
Is Microsofts C++/CLI built on top of the C++ Standard (C++98 or C++11) or is it only "similar" and has deviations?
Or, specifically, is every ISO standard conforming C++ program (either C++98 or C++11), also a conforming C++/CLI program?
Note: I interpret the Wikipedia article above only comparing C++/CLI to MC++, not to ISO Standard C++.
Sure, it is an extension to C++03 and can compile any compliant C++03 program that doesn't conflict with the added keywords. The only thing it doesn't support are some of the Microsoft extensions to C++, the kind that are fundamentally incompatible with managed code execution like __fastcall and __try. MC++ was their first attempt at it, kept compatible by prefixing all added keywords with underscores. The syntax was rather forced and not well received by their customers, C++/CLI dropped the practice and has a much more intuitive syntax. Stanley Lippman of C++ Primer fame was heavily involved btw.
The compiler can be switched between managed and native code generation on-the-fly with #pragma managed, the product is a .NET mixed-mode assembly that contains both MSIL and native machine code. The MSIL produced from native C++ source is not exactly equivalent to the kind produced by, say, the C# or VB.NET compilers. It doesn't magically become verifiable and doesn't get the garbage collector love, you can corrupt the heap or blow the stack just as easily. And no optimizer love either, the MSIL gets translated to machine code at runtime and is optimized just like normal managed code with the time restrictions inherent in a jitter. Getting too much native C++ code translated to MSIL is a very common mistake, the compiler hides it too well.
C++/CLI is notable for introducing syntax that got later adopted into C++11. Like nullptr, override, final and enum class. Bit of a problem, actually, it begat __nullptr to be able to distinguish between a managed and a native null pointer. They never found a great solution for enum class, you have to declare it public to get a managed enum type. Some C++11 extensions work, few beyond the ones it already had, auto is fine but no lambda expressions, quite a loss in .NET programming. The language has been frozen since 2005.
The C++/CX language extension is notable as well, one that makes writing C++ code for Store and Phone apps palatable. The syntax resembles C++/CLI a great deal, including the ref class and hats in the syntax. But with objects allocated with ref new instead of gcnew, the latter would have been too misleading. Otherwise very different from C++/CLI at runtime, you get pure native code out of C++/CX. The language extension hides the COM interop code that's underneath, automatically reference-counting objects, translating error codes into exceptions and mapping generics. The resemblance to C++/CLI syntax is no accident, they basically perform the same role. Mapping C++-like syntax to a foreign type system.
CLI is a set of extensions for standard C++. CLI has full support of standard C++ and adds something more. So every C++ program will compile with enabled CLI, except you are using a CLI reserved word and this is the weakness of the extension, because it does not respect the double underscore rule for extensions (such reserved words has to begin with __).
You can deactivate those extensions in the GUI by:
Configuration Properties -> General -> Common Language Runtime Support
Even Bjarne Stroustrup calls CLI an extension:
On the difficult and controversial question of what the CLI binding/extensions to C++ is to be called, I prefer C++/CLI as a shorthand for "The CLI extensions to ISO C++". Keeping C++ as part of the name reminds people what is the base language and will help keep C++ a proper subset of C++ with the C++/CLI extension
Language extensions could always be called deviations from the standard, because it will not compile with a compiler without CLI support (e.g. the ^ pointer).
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.
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.
What is the Objective-C equivalent of the Java Language Specification or the C++ Standard?
Is it this:
http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html ?
(I'm just looking for an (official) authoritative document which will explain the little nitty-gritties of the language. I'll skip the why for now :)
Appendix A of the document you linked to is a description of all of the language features, which is the closest we have to a specification (Appendix B used to be a grammar specification, but they've clearly removed that from the later versions of the document).
There has never been a standardisation of Objective-C and it's always been under the control of a single vendor - initially StepStone, then NeXT Computer licensed it (and ultimately bought the IP) and finally Apple consumed NeXT Software. I expect there's little motivation to go through the labourious process of standardisation on Apple's part, especially as there are no accusations of ObjC being an anticompetitive platform which standardisation could mitigate.
There is none. The link you provided is the only 'official' documentation, which is essentially a prose description, and not a rigorous language specification. Apple employees suggest that this is sufficient for most purposes, and if you require something more formal you should file a bug report (!). Sadly, the running joke is the Objective-C standard is defined by whatever the compiler is able to compile.
Many consider Objective-C to be either a "strict superset" or "superset" of C. IMHO, for 'classic' Objective-C (or, Objective-C 1.0), I would consider this to be a true statement. In particular, I'm not aware of any Objective-C language addition that does not map to an equivalent "plain C" statement. In essence, this means the Objective-C additions are pure syntactic sugar, and one can use the C standard in effect to reason about the nitty gritty. I'm not convinced that this is entirely true for Objective-C 2.0 with GC enabled. This is because pointers to GC managed memory need to be handled specially (the compiler must insert various barriers depending on the particulars of the pointer). Since the GC pointer type qualifiers, such as __strong, are implemented as __attribute__(()) inside gcc, this means that void *p; and void __strong *p; are similarly qualified pointers according to the C99 standard. The problems that this can cause, and even the ability to write programs that operate in a deterministic manner, are either self evident or not (consult your local language lawyer or compiler writer for more information).
Another problem that comes up from time to time is that the C language has continued to evolve relative to the Objective-C language. Objective-C dates back to the mid 1980's, which is pre-ANSI-C standard time. Consider the following code fragement:
NSMutableArray *mutableArray = [NSMutableArray array];
NSArray *array = mutableArray;
This is legal Objective-C code as defined by the official prose description of the language. This is also one of the main concepts behind Object Oriented programming. However, when one considers those statements couched from the perspective of "strict superset of C99", one runs in to a huge problem. In particular, this violates C99's strict aliasing rules. A standards grade language specification would help clarify the treatment and behavior of such conflicts. Unfortunatly, because no such document exists, there can be much debate over such details, and ultimately result in bugs in the compiler. This has resulted in a bug in gcc that dates all the way back to version 3.0 (gcc bug #39753).
Apple's document is about the best you're going to get. Like many other languages, Objective-C doesn't have a formal standard or specification; rather, it is described mostly by its canonical implementations.
Further resources include:
The Objective-C Language and GNUstep Base Library Programming Manual.
The NeXT developers library
Apple (now) using clang of the llvm.org project.
Some of the language elements are defined in this context
e.g. Objective-C literals --> http://clang.llvm.org/docs/ObjectiveCLiterals.html
But i didn't found a clear overview of all elements.
--- updated --
The source of Apples clang is available (as open source) here:
http://opensource.apple.com/source/clang/
I've found references online that talk about two different root classes for ObjC, either objc/Object.h or Foundation/NSObject.h. They require different compiler flags (-lobj vs. -lobjc -framework Foundation, and have different selectors for initializing & releasing objects. Is NSObject a replacement, or do they have different applications? Obviously NSObject.h would be better for NextStep-type stuff, but does Object.h have advantages that would make it better in certain situations?
FWIW, the updated FAQ from comp.lang.objective-c seems to indicate the NSObject.h is correct; an older version mentions Object.h
My understanding of the situation is there are two runtime libraries for Objective-C. Apple's library, which uses NSObject, and the GNU library which uses Object. If you are developing for an Apple platform, use their runtime. If you're developing for a non-Apple platform, you use the other.