Direct

Direct Train

After playing around with the the Objective-C mixins code a little, I still hadn’t tested cross-class instance variable access.

I’ll start by mentioning two things I forgot to mention previously; this code is highly experimental, and you shouldn’t attempt to map a method onto another class unless you control the implementation. Unless you control the original method, there’s no way to know what the method is doing, and no guarantee that it won’t change.

The problem appears when accessing instance variables directly; the solution is obviously not to, and to go through accessors, but I still needed to know why it wasn’t working. Consider the following two lines of code:

*(id *)((int8_t *)self + ivar_getOffset(class_getInstanceVariable([ClassA self], "_delegate")))

*(id *)((int8_t *)self + ivar_getOffset(class_getInstanceVariable([self class], "_delegate")))

Both accomplish the same thing but feature a subtle difference; the first uses a constant value for the class – the class the method is being compiled into – the second uses a dynamic one. These are only approximations of what the compiler generates, when I inquired why there’s a discrepancy I was told it’s due to the performance implications. When direct instance variable access is compiled, it takes the form of the first example – for mixin methods if you insist on directly accessing instance variables, you’ll have to write access of the second form yourself.

Photo by itmpa

Boolean

Optionally

In certain languages there’s an argument passing convention where you pass a pointer when a boolean is expected. It’s something of a moot point since in these languages there’s often no concept of pointers anyway. And whilst there’s nothing wrong with doing it in these other languages, there is when porting this convention to C where we do have pointers.

Non-nil pointers could be read as false if cast to a boolean.

Boolean types are primarily used in two places:

  1. Primitive flow control constructs, such as if and while.
  2. Passed as arguments to functions and methods.

Whilst pointers-as-booleans will work in the first case, it can break in the second case. Which is illustrated nicely in this paradoxical example.

ZIPPointers-As-Booleans

The reason it works in the first case is because of how the code is compiled. Looking at the x86 assembly yields:

LM5:
leal L_main$non_lazy_ptr-"L00000000002$pb"(%ebx), %eax
movl (%eax), %eax
subl $116, %eax
movl %eax, -12(%ebp)
LM6:
cmpl $0, -12(%ebp)
je L8

The comparison is performed using the cmpl instruction with zero as a literal argument, and the conditional is performed using the je instruction. The net effect being that if the argument (named valueRef in the source) is equal to zero, the instruction pointer will jump to the address labelled L8. Compare that with the conditional to print either TRUE or FALSE inside the +[Logger print] method:

LM2:
cmpb $0, -12(%ebp)
je L2
leal LC1-"L00000000001$pb"(%ebx), %eax
movl %eax, -16(%ebp)
jmp L4
L2:
leal LC3-"L00000000001$pb"(%ebx), %edx
movl %edx, -16(%ebp)

The difference in instructions is subtle, but here the comparison is performed using the cmpb instruction which compares bytes – where as cmpl compares words. This is where the truncation occurs. Because valueRef is decidedly non-nil the the -print: method does get called. However, when you compare the first (Intel being Little Endian of course) byte only, it’s empty which causes FALSE to be printed.

The behaviour observed can be seen as unique to the 32 bit Intel instruction set. If you recompile the example for PowerPC it will print TRUE because, the cmpwi instruction in PPC assembly compares thirty-two bits instead of the eight compared by cmpb.

As I pointed out back at the beginning, this phenomenon is succinctly explained by simply stating that casing a pointer to a BOOL is downcasting, and the compiler complains to that effect – but only in the second case – which is both my problem and point.

I’m uncomfortable with the disparity observed between using a pointer in flow control, and as a typed argument. Using a pointer where a primitive boolean type is expected, in a language where pointers are explicit types, should be considered harmful, lest it leads to their usage as arguments. I simply advocate a nil comparison in both cases, which ensures a boolean result.

Photo by gianca

Camouflage

Camouflage

It is the job of the dynamic linker to stitch your program together at runtime, so why not exploit that and create your own dynamic links.

Some of the problems typically solved by multiple inheritance could also be solved if Objective-C protocols allowed for a user defined implementation however, for the moment they don’t. It’s easy to use the runtime functions to dynamically add methods to a class. You could do it in a class initialisation function, but that wouldn’t work for a class category. Ideally the solution should work in tandem with the dynamic linker, just as each Mach-O bundle can contain Objective-C classes each should also have the option to contain a ‘mixable’ directive.

Based on the procedures I already developed to encapsulate class metadata, it was trivial to extend them using the hooks provided by dyld, to produce mixin behaviour. The sample project below includes the code required and example usage.

ZIPMixins

Briefly, the project includes a property list which provides the selector to implementation mapping that should be enacted at runtime, this file is included in the executable using the sectcreate linker switch. I plan to move the code into Amber where the setup code can be called in the framework initialisation routine, allowing an application to simply link against Amber and use mixins without further configuration.

As the code is fairly self explanatory, I’ve left out any lengthy discussion however I would like to encourage questions and critique. Perhaps, there is a better way to accomplish this? Personally I’d like it to be more programatic; or based on markup in the implementation files.

Photo by bmelancon

Diversity

Doormat

Bonjour, is the Zeroconf solution from Apple. The specification emcompasses a few elements but the most exciting part is serverless discovery of network services, and the classes provided in Cocoa used to interact with them.

Using Bonjour in Cocoa is really easy, there are two fundamental classes, and two procedural interfaces that underpin them. The protocol used to implement this functionaity is Multicast DNS, and the DNS Service Discovery extensions. Both iPhone OS and Mac OS run a background process called mDNSResponder which; serves as the endpoint for local queries, listens for the multicast packets and maintains a cache of records. Whilst you could join the multicast group yourself and implement raw support in your application, it’s much easier to use the existing high-level interfaces which communicate with the background process.

For a more in-depth discussion of the technology behind Bonjour watch “Zero Configuration networking with Bonjour” a talk given by it’s inventor, Stuart Chesire.

Much like the rest of the framework classes, NSNetService and NSNetServiceBrowser only implement basic functionality. Unfortunately, if you want to implement custom behaviour on a discovered service, the browser won’t return your subclass. You might be tempted to write either a custom browser class or a wrapper, but I’ve yet to find the need. If you treat the browser callbacks as an exercise in pattern matching, you’ll save yourself a lot of code. The problem here is to create a custom object represenation of the discovered service, without having to reimplement high-level service discovery to create that object for you. It turns out that it’s actually quite simple.

I accomplished it by defining an object to represent a service, a regular NSObject subclass, and instantiating it with the name, type and domain from the discovered NSNetService. You also need to define a custom equality method that is based purely on these properties, and return the hash of the name string as its own (the service name is guaranteed to be unique for discovered services so you can use it to index the object). When your browser notifies you of a new service, instantiate your custom class and store a reference to that instead. When your browser notifies you that a service has disappeared, you can use the NSNetService passed to your callback to remove your custom instance from any collections that you’ve stored your object in. Because you defined the equality method to use the name, type and domain strings it will match.

Whilst the behaviour you want will vary for each service type; a common behaviour I felt was missing was key value observing for TXT record keys. NSNetService will notify a single listener using a delegate method, but I wanted to observe the values in several places. Additionally, the code sample below includes a function for converting the the whole TXT record to NSString objects. The NSNetService class method only converts the keys to strings, because it can’t rightly assume that the values will be strings too. The service types I’ve used (and defined) so far are only using string values. Building on the existing functionality by replacing the value objects in the dictionary with their UTF8 encoded NSString counterparts has proved much more useful in practice.

ZIPNet Services

I could have simply created an object which created it’s own internal NSNetService for the name, type and domain. But then I wouldn’t have been able to resolve it or treat it like an actual NSNetService. However, remembering that it is simply a pattern which you can duplicate any number of times, you don’t have to resolve the service object that you use to monitor the TXT record, I simply found it convenient to.

I included the ChatService class for academic reasons, to show an example of specific case usage. It should be noted that it isn’t a complete implementation of the requirements since it doesn’t implement the recommended caching behaviour.

Photo by dolarz

Static

Static Motion

One of my biggest gripes with Objective-C; is that there’s no way to generate a static array like you would with string constants or regular C arrays.

What I tend to do is create an extern variable and then assign it in a class’ initialize method. If I have dependencies then I typically initialize them in the application delegate’s respective method, but this is fragile and has cost me time debugging in the past. What I really need is class metadata, static serialisations.

My solution came about because I found myself writing certain class accessor methods over and over. NIB names, window titles, button titles, things that are implicit to a class in a given situation and that don’t benefit from inheritance. What I could have done was create a single class method to return a constant-string keyed dictionary of properties. This has the advantage of not being limited to property list objects. Or I could have simply inferred some of the metadata from the class name as you would in Rails, though that’s fragile, and wouldn’t be obvious to someone new to the codebase. However both involve writing additional code per property, which requires code changes and some one to make them. Instead I developed a solution that allows an executable to be repurposed without having to change any code. You can change the metadata, and hence the behaviour with compile time settings rather than clever glue-code.

What I needed was a runtime mapping from class names to a collection of predefined and instantiated variables, solving the call graph dependency and reentrancy issues. Whatever the solution, it should work whether the class originated from a framework or an application, it shouldn’t assume from which bundle a class originated from either. Loading a framework should include any metadata from there too, even though this introduces the same namespace issues that categories do. The only thing you are assured of in both cases is a Mach-O binary. And whatever the solution, it should provide a minimal interface. I’ve come up with an implementation that exposes only a single public function (plus some other stuff).

As the platform has matured we’ve moved away from writing code favoring the graphical editors instead, Core Data models and Quartz compositions are good examples. In this case we’re going to use the Property List Editor, resticting the objects that we can map to the property list set, but we aren’t going to simply include this in the application bundle, that’s for runtime resources. Class metadata should be assigned at compile-time, and simply coalesced at runtime. Just to be clear: I’m not adding class variables to Objective-C; I’m adding a readonly mapping between a class and a list of properties. But the list of what you could do with this data is practically endless.

To include this plist in the product without having to write the code to load it from the resources folder, we need to include it in the binary itself. There’s a little known feature of the linker that can include an arbitrary file in the binary using the sectcreate switch. The list of reserved sections and segments can be found in the documentation. We’re going to put the metadata into __OBJC,__class_metadata. To do this add the following command to your “Other Linker Flags” build setting:

-sectcreate Linker Flags

The structure of the plist you include is important for the function I’ve written. It should contain a root dictionary, mapping class name strings to any other plist object. Warning: this example code contains low-level Mach-O functions, those of a nervous disposition should look away now.

NSObject+Metadata

It’s not perfect yet, there are still a couple of #warnings in the implementation that need polishing off. Assuming you use a dictionary for a class’ root metadata object, you’ve still to use pre-declared strings to access the variables. Perhaps the plist XML could be generated from markup in source files, that way the keys would be defined natively but it would require a recompile to change a property.

This is as close as I could get to static NSArray instances, the code can also be found in AmberFoundation, which now compiles for iPhone OS too.

Marathon

Recently I’ve been getting a lot of questions about the runpath linker feature new in Leopard. I think the primary issue is that there are two runpath settings that you have to configure.

Before we talk about how to make use of runpaths, we should look at why they are needed. Previously, you might have prefixed a library install path with @executable_path or @loader_path. The problem with this is that it puts the onus on the binary which links to the library to maintain an expected bundle structure. Case in point, application and framework bundles have a different layout with regard to their Frameworks folder, respectively @executable_path/../Frameworks and @loader_path/Frameworks. The introduction of runpaths solves this by instead having the bundle’s binary specify where it’s libraries can be found.

Runpaths are simply used to specify a dynamic location for a shared library. They aren’t used by the compiler, they’re used by the linker. And they aren’t used to find the libraries at link-time either – that’s what the search paths are for – they are only used at runtime.

When linking your binary, the linker is only passed the library name for each library, and relies on the search paths to find them. Where frameworks and libraries are at link-time has no bearing on where they are expected at runtime. A dynamic library contains an install path, this is the location on disk that a bundle can expect to find it. If you run `otool -L /path/to/binary` against a Mach-O binary you’ll get a list of which libraries the binary links to, and where it expects to find them:

$ cd ~/Projects/Build Products/Debug/Sample.app/Contents/MacOS/
$ otool -L Sample

Sample:
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0)
@rpath/Amber.framework/Versions/A/Amber (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.0.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.12.0)

As you can see above the ‘Sample’ binary links to Amber and expects to find it at ‘@rpath/Amber.framework/Versions/A/Amber’. This is where the second setting is used, in order for dyld (the dynamic linker) to find the library at runtime, it consults the binary’s runpaths and substitutes them in place of the @rpath token. The runpaths can be absolute paths or use the relative tokens @executable_path and @loader_path. In the latter case the tokens will be replaced by the actual path at runtime.

The most common mistake is forgetting to copy the shared library to your bundle; or specify your executable’s runpaths. Note that even if you forget to copy the library into your build product, your executable will still work when launched under Xcode.

Succinctly, the runpath feature consists of two components, an install path prefixed with @rpath, and a list of directories that should be searched at runtime.

Photo by thebigdurian

Command

I was surprised to learn that you couldn’t pass an Xcode Configuration Settings file to xcodebuild, it seems like such a logical feature.

Xcode Configuration Settings are a really useful Xcode feature, allowing you to share and group settings together so they can be reused. They are particularly useful when sharing an iPhone project file; each developer on the project can specify their own CODE_SIGN_IDENTITY in a file which, though included in the project, isn’t checked in to source control.

I’m building a product that can contain various different sets of resources. I wanted to script the build so that whomever ends up building the product can swap the resources out without having to change anything in the project. I also needed Xcode to build a default product containing a subset of those resources for testing purposes.

Ideally xcodebuild would include a ’settings’ switch (which would have saved me having to knock this together) but it doesn’t. I hacked a Ruby script together which wraps xcodebuild, extracts the aforementioned ’settings’ switch and passes everything else though. I’ve included it here as an example.

xcodebuild+settings.rb

I also discovered something interesting about Ruby whilst writing this script, I mutated a collection whilst enumerating it, which worked!

Photo by mszippycat