Learn Objective-C on the Mac - Mark Dalrymple [162]
Filtering
Another use of blocks that Apple has added to Cocoa is NSArray’s indexesOfObjectsPassingTest: method. This method lets you declare a block that will examine an object, and based on your own criteria determine whether it should be included in the set of indexes that comes out (which can in turn be used to extract the “successes” from the original array. For example, assuming you have an array of people, you can find all the people named “Bob” like this:
Although the use of blocks may seem tricky at first, after a while they become second nature, and once you get started, you’ll probably find more and more ways to use them. They are a really important tool for every Cocoa programmer moving forward.
Cocoa in a Foreign Language
As much as some of us love Objective-C, it’s not the only game in town, and some people would rather use another language for developing Cocoa apps. Maybe you have a particular code library you want to make use of, or maybe you just prefer some other language. The good news is that there are some languages out there that can interface with Objective-C well enough to allow for some Cocoa development, through the use of what’s called a “bridge” between the other language and Objective-C.
The bad news, for some people at least, is that two of the biggest, most popular languages, C++ and Java, aren’t among them. You may be wondering why not. Well, without getting too deep: C++ and Java are just too inflexible. They don’t have the sort of runtime introspection capability that’s required for fully interfacing with complex Objective-C class libraries like Cocoa. Maybe, technically, Java has got what it takes. In fact, Apple included a Java bridge for building Cocoa apps in the first several versions of Mac OS X. But the fact that programmers weren’t lining up at the gates to use it, combined with the technical challenge of implementing and maintaining the Java bridge, just made it not worthwhile for them, and Apple abandoned the project several years ago. And because you can actually combine Objective-C and C++ together in the form of Objective-C++, the need for bridging there is somewhat reduced. There are some real limitations there. You can’t, for instance, implement an Objective-C delegate in the form of a C++ class, so you’ll need to create some “glue classes,” typically paired up across the border (one C++, one Objective-C) that are each able to deal with their own world and translate things for one another. It works, but believe me, that sort of code is not much fun to write or maintain.
Back on the good news side of things, some of the languages whose usage is still increasing year-by-year, such as Python and Ruby, have solid, working bridges that let you do real Cocoa work with them.
PyObjC
One of the earliest projects to bridge a non-Objective-C language with the Cocoa frameworks is PyObjC, which lets you do a significant amount of Cocoa development in Python. As you’re well aware by this point, Objective-C’s syntax, in particular the intermixing of method names and arguments, is somewhat unusual, and most other languages don’t have any equivalent. What PyObjC does is provide mappings for all methods in all Objective-C classes included in Cocoa, so that you can call them from Python. The mappings are determined by a pretty simple formula: the entire Objective-C method name is pushed into a single symbol, with each colon in the method name replaced by an underscore character. All the method arguments are sent between parentheses, just like a standard C function. All objects are automatically bridged, so that you can use all the standard Cocoa classes right from Python. For example, let’s look at a line of code we showed earlier, when talking about notifications. Here’s the Objective-C version:
As you can see, the lack of intermixed method-name-parts and arguments really impacts the readability. Also, on the whole it’s rather “un-Pythonic,” so, while it works well for what it does, there are things for all sides to be somewhat