Things Developers Should Know About Leopard
Leopard brings a lot of changes for Mac programmers. If you haven't been tuned in, here's a cheat sheet of some things you'll want to be aware of in the coming months and years.Changes in Tools
Xcode is getting major upgrades for Leopard. There are some high-level UI features like code highlighting and inline errors and warnings, but some of the bigger changes are refactoring support and Snapshots. The refactoring hits not just code but also bindings and such in NIB files. Snapshots work as a sort of low-tech version control that allow you to muck around with some experimental changes and then snap back if it isn't going to way you want.
Interface Builder is a brand new application. It's a complete rewrite — at least from the user's perspective. After using this for more than a year, I can tell you I'm really excited about how much more polished the process of creating and editing user interfaces feels in Leopard. The app feels very solid, look gorgeous, and adds many things that users have long waited for. You can even add Core Animation effects visually from IB.
There's a brand new performance measuring tool in Leopard called Xray. The user interface is clearly based on the GarageBand-ish model, with each "track" displaying a different aspect of performance, such as memory consumption, CPU load, etc.
Languages
In case you haven't heard, Objective-C 2.0 is a major revamp of the language. There's garbage collection (opt-in), properties with synthesized accessors, a foreach language construct, dot-syntax support for accessors, and much more. It's a good thing.
Several scripting languages are getting the official Cocoa language bridge treatment, including Ruby and Python. Some see this as "no need to learn Objective-C," which may be the case for many situations — but really I think developers should view this as another tool in their toolbox.
Neither Ruby nor Python are drop-in replacements for Objective-C. Each languages has its strengths and weaknesses. But certainly official support for scripting languages makes it easier to get started writing Cocoa apps. For me, one of the most interesting uses of these bridges are creating Cocoa UIs on top of existing administration tools.
Core Animation
Core Animation is not just for animation. Yes, it does 3D towers of album artwork very well, but this framework offers a completely different way to do graphics programming. A lot of the manual work you had to do in a custom view prior to Leopard can be handed off to a layer in Core Animation. Not only does this make the code simpler, but it also means the app can potentially be much more responsive because the rendering happens in a separate thread.
There's much, much more say about this, but it will have to wait until Leopard ships. I really think this framework will be as significant to Leopard as Cocoa Bindings was to Panther or Core Data was to Tiger.
Other Stuff
Core Data now allows you to write your own custom stores with NSAtomicStore, which is something I think a lot of people have been waiting for. Core Data also now includes a formal process for migration and schema versioning.
FSEvent offers file system notifications, which may save you from mucking around in kqueue events. As we know, Leopard will also be the start of a real push for resolution independence. Icons will need to go as high as 512x512 pixels, for example, and custom views should not assume that one pixel is one unit.
This is all just an overview of a bunch of stuff that popped into my head. I've written a lot of Leopard code this year, reading about the new APIs practically every day for months, and I still don't feel like I have a complete picture of what's available. There are tons of new frameworks everywhere, and drastically upgrades to most of the existing frameworks. There's plenty to chew on here for a while.
Also, the application frameworks now have full 64-bit support.
Things Developers Should Know About Leopard
Posted Sep 21, 2007 — 34 comments below
Posted Sep 21, 2007 — 34 comments below
Ted — Sep 21, 07 4617
Chris — Sep 21, 07 4619
Carbon doesn't.
Dewayne Christensen — Sep 21, 07 4620
Scott Stevenson — Sep 21, 07 4621
I'm not sure that sort of stuff is public knowledge.
Daniel — Sep 22, 07 4623
Does application written in Objective C 2.0 works for Tiger? Or is it only for Leopard onwards?
Udo — Sep 22, 07 4624
Pieter Omvlee — Sep 22, 07 4625
I'm just getting started with my application (DrawIt), and there already is an icon of 128x128.
I know this is too small for Leopard, but how necessary is it really to get a bigger icon?
DrawIt has only just got out and hasn't sold much; is it already worth the investment of a few hundred euros (I do want to carry on with the application, hopefully as an independent developer) or can I wait?
Are we going to see those big icons only in the CoverFlow-finder interface or also in other places?
Scott Stevenson — Sep 22, 07 4626
There are two reasons you want 512 size icons. The first is the obvious one: larger scaling factors will be available to users before too long, and your icon won't look good if it has to scale up. But this feature doesn't have an announced ship date yet (though some guidance was given at WWDC).
The other reason is the one you allude to: the CoverFlow feature in the Finder. Even from just screenshots on the public site, you can see, icons in that view are displayed at a much larger size than the typical Finder window.
Your icon won't break in either case, it will just look all pixely if it's scaled up. And yes, that is the technical term. Pixely.
Davi — Sep 22, 07 4627
Carbon doesn't.
Question: if I want to show a picture of dimensions greater than 2^16 x 2^16 pixels, does anything Leopard make it easier, now that it is 64-bit? ("Show" == render a downsampled version, zoom in/out, scroll around in higher res versions, etc.)
Ted — Sep 22, 07 4628
Jesper — Sep 22, 07 4630
64-bit does one thing: it makes it possible to have a larger *memory* space than 4 GB. With 32-bit, you'd have to have a memory window that you'd move around "over" that data, loading it in as you go.
Such capabilities have been available for the G5 in executables that just link with the standard system library (lower than even Core Foundation). In 10.5, it's available for Intel 64-bit processors (Xeon and Core 2 Duo), and it's also available for Core Foundation, Cocoa and most of the non-UI bits of Carbon.
If you previously had a window in a (32-bit) UI application communicating with a 64-bit application managing the data access, and the 32-bit application only handled showing the pixel data the 64-bit app threw at it, and the 64-bit app handled scaling, then you wouldn't see a difference in speed. But for almost any other situation involving such a large image, it'll be faster and you'll be able to write just the one, 64-bit app.
How would one write a OSX GUI app that targets both Tiger and Leopard?
One would write a Tiger version.
Davi — Sep 22, 07 4633
64-bit does one thing: it makes it possible to have a larger *memory* space than 4 GB. With 32-bit, you'd have to have a memory window that you'd move around "over" that data, loading it in as you go.
Sorry, still not clear. I'm not too familiar with Cocoa, but let me try to re-pose the question in more specific terms: are you saying that in Leopard, with adequate quantities of RAM, I could allocate an NSImage with size = 100,000 x 100,000 pixels, and then have an NSImageView show it to me? If not, are there any other new Leopard-y libraries that would be able to do such a thing?
Or would I have to implement a G5-ish "32 bit viewer of 64 bit data" pattern like you describe above?
(I'm asking this because I actually do have image data of these dimensions, and it would be very nice if there were a toolkit that could handle them.)
Chris — Sep 22, 07 4634
Chris — Sep 22, 07 4635
Nib files can already be text in Tiger -- you just have to explicitly save them as such. It doesn't help a heck of a lot, because any single change appears to cause all of the object IDs in the file to change. The non-public question is whether or not Leopard fixes that problem.
Blain — Sep 23, 07 4638
Is there a publically, non-NDAed list of which make the jump? Something ironically like when we were jumping to Carbon in the first place? I've got a few carbony calls with IconRefs and FSRefs, and while there'd be not much lost in staying 32-bit, I'm curious.
Actually, scratch that. More importantly, which systems are supported? Does it matter if my G3 has a G4 processor upgrade? Of course, these are all rhetorical questions until the NDA veil is lifted off of them, but they still are something of a concern to me.
Chris — Sep 23, 07 4644
I don't know the answer to your second (if I did, I couldn't answer due to NDA), but I can give you an educated guess based on past experience: Apple tends not to support processor upgrades, so you'll need something like XPostFacto to make that work.
Scott Andrew — Sep 26, 07 4647
As far as Objective C 2.0. My next product is targeting leopard and the layers are saving me a lot of work. Properties and garbage collectoin are great as well and simplify programming. My one concern with garbage collection and properties is how many abusive apps there will be at first. Ther are definately things to do and not do when it comes to properties and when to copy vs retain values.
I do think, however, the new changes to the language are a great addition. And only wish 10.4 would support them.
As far as layers. The biggest thing here, at least for me, is putting subviews ontop of OpenGL and QT layers. This is a big time saver, fast, and a great feature. It allows for easy interactive controls on view's that didn't allow subviews before. And all drawing is HW accelerated..
Apple has done a good job of modernizing a great UI. Leopard is fast, looks great, productive, and is a welcome update form 10.4
Scott Stevenson — Sep 26, 07 4648
Can you elaborate on what you mean by this? It's hard to see how properties could be abused in any way. And even abusing garbage collection seems like a bit of a stretch (in my opinion).
Panagiotis Atmatzidis — Sep 26, 07 4649
As a novice programmer, I'm still learning ObjC basics! I'm reading about "Inheritance" right now. I'd like to know if Objective C 2.0 will introduce a different way of approaching things in a way that could affect my learning curve. Should I wait for an Objective C 2.0 specific manual to be released or can I keep reading the basics of the language as I do now?
Thanks,
regards
Daniel — Sep 26, 07 4650
This annoys me a bit. Here I am mucking about with creaky old IB 2, trying to do *standard things* because I wasn't privileged enough to get a copy of Leopard from the WWDC over a year ago. It's like there's an elite class of Mac users out there who have access to all this wonderful stuff (and they can't talk about it because of the NDA) while Apple leaves the rest of us to use artificially-crummy tools because they want everyone to upgrade to Leopard on day one. Which is fair enough...except Leopard is delayed. Grrr.
XCode 3.0 and the new Interface builder have been feature-complete for over a year now. At least on Windows I can try out the latest Dev tools without upgrading to Vista.
(end rant)
Chuck — Sep 26, 07 4651
Everybody has had the same opportunity to purchase a Leopard preview for more than a year now. You still have the opportunity. There is no elite class that was simply handed everything. If you've decided that having the tools ahead of time isn't worth it to you, it seems like sour grapes to complain now that you don't have them. (By the way, the new tools contain several Leopard-specific features, so they couldn't just release them for Tiger.)
I don't mean to sound condescending. I didn't do it either — the cost simply wasn't justified for me. But hey, it was our choice, right?
Scott Stevenson — Sep 26, 07 4652
The Leopard tools use Leopard-specific APIs, so they will not run on Tiger.
XCode 3.0 and the new Interface builder have been feature-complete for over a year now.
Who said that?
Scott Stevenson — Sep 26, 07 4653
There's no reason to wait, in my opinion. Objective-C 2.0 doesn't really remove anything from the high-level language stuff, so everything from 1.0 still applies. There are just new options available to you.
The only thing that arguably becomes irrelevant is memory management, but not all code will be garbage collected from day one, so it will be valuable to understand retain/release/autorelease for some time.
Clark Goble — Sep 26, 07 4655
Daniel — Sep 26, 07 4656
That's another thing. Everyday now someone else announces a new 10.5-only app which seems premature for a as-yet-unreleased OS no matter how good the APIs are.
Scott, has Apple fixed the debugger yet? It's ridiculously slow to do anything in 2.4.1. Just starting the app takes an age. It doesn't have a patch on VS's debugger? If they fix anything let it be that!
Scott Stevenson — Sep 26, 07 4657
I'm not sure what to say to this. Leopard has a lot of enhancements to the frameworks, tools, and runtime system. It's each developer's individual decision as to whether those benefits are worth adopting the new OS. As for being premature, I don't see how it really matters if they announce the apps now or after October. The software is the same.
Scott, has Apple fixed the debugger yet? It's ridiculously slow to do anything in 2.4.1.
I'm not sure how to answer this.
Stripes — Sep 27, 07 4658
When I first learned Java I did things I consider "GC abusive", mostly to see if I had to bother to be "clever", or if "dirt simple dumb" would be fast enough.
I wrote a SSH client (plus terminal), and when I dealt with packets and sub frames and things I just plopped each packet into a string, and then ripped the packets into strings for each subframe and on and on. The "efficient" way would have been to use a single string (or string buffer) and pass index/length pairs around for packets, sub frames and the like.
Turns out it was more then fast enough. Faster then MS's built in telnet in fact. (this was my attempt to both learn Java and see if I could develop on a windows platform...it worked out Ok, and I've done a little more with Java since then, but the Windows box only ever played games after that, until something or other died on it and I haven't bothered to resurrect it).
Scott Andrew — Sep 27, 07 4659
As far as garbage collection comming from a .NET world where collection is not very agressive, i have seen graphics apps or video apps be very very large in memory when using managed code. But i am glad to say my tests haven't shown it show far with apples implementation. It appears the garbage collection works well. So my garbage collection comment may have been wrong. However the use improper use of copying large objects around with properties does concern me. I know the use or retain for properties of objects, even with garbage collection, appears to be more efficient than copy. I think copy works better for non managed objects (C++ and C variables).
Scott Stevenson — Sep 27, 07 4660
It depends on how the class of the object you're setting implements copy. Doing a copy of an immutable object (NSString, for example) will often just return the same object. I'm not sure offhand what happens with NSData and NSImage, but it wouldn't surprise me if they work this way as well. Another possibility is that you get a new object but the data it references is not copied.
My first reaction to what you wrote was that the point is moot because "copy" is not a new concept. However, after meditating on it, I see what you mean. It's much different when you can just say "copy" in the property definition and not even look at the implementation. You just start duplicating the property lines and suddenly all of your setters use copy, whether it makes sense or not.
So, yes. I do see what you mean. But I don't think it's likely to matter in the grand scheme of things.
Blain — Sep 29, 07 4661
NSImage * testImage = [[NSWorkspace sharedWorkspace] iconForFileType:@"txt"]; NSImage * copyImage = [testImage copy]; NSLog(@"Image: %@ vs %@",testImage,copyImage); NSEnumerator * ourEnumerator = [[testImage representations] objectEnumerator]; NSBitmapImageRep * thisRep; while (thisRep = [ourEnumerator nextObject]){ NSLog(@"Test image representation %x has bytes at %x", thisRep,[thisRep bitmapData]); } ourEnumerator = [[copyImage representations] objectEnumerator]; while (thisRep = [ourEnumerator nextObject]){ NSLog(@"Copy image representation %x has bytes at %x", thisRep,[thisRep bitmapData]); }
All the addresses are different when I run this. NSImage -[copy] copies all the way down. And given that NSData has secondary messages that explicitly mention nocopy, you can have it either way.
@Daniel: Could be worse. I'm so behind the curve in hardware, my keyboard is still ADB!
Also, wasn't MS Dev studio non-free for the longest time? Even now, express has some limitations. In which case, the difference is that we'll eventually get IB 3.0 for free*, as opposed to always being the have-nots.
*Okay, $129, most likely.
Steve Weller — Sep 29, 07 4662
You can't conclude that the "copying" is all the way down just because you get different addresses back. It depends on the implementation.
If the object you copy is mutable then an efficient copy can't reuse the object data directly like it can with a mutable one -- what would happen if you modified it? But it can give you back a proxy object with a new address and track which proxies are sharing the actual data.
Only when a write occurs does the data (or part of it) actually get copied. Or even better, the changes are tracked and nothing gets copied until the data is actually used for something. "Copying" may do very little until the address of the bit map is returned to you.
Blain — Sep 29, 07 4663
I'd agree, except I'm checking all the way down. BitmapData is a type char*, or void*, and diddling here changes individual pixels. Either way, that is the base bit data, with no further pointers or metadata. The program shows that the actual data is in actually different locations. So in this case, there's no way, except some serious voodoo.
I suppose you can do akin to how forked processes handle copied memory. That is, copy on write. But that'd require this single thread to have two different memory addresses to point to the exact same location in a page. It's possible, but downright scary. Not only that, but were that the case, I'd expect to see the same offsets from page boundaries, which wasn't the case.
The other notable hint is that the convention seems to be that immutable objects retain instead of copy, but mutable objects copy to an immutable version. This is how it is with NSString and NSArray. But NSImage isn't immutable. The base class is mutable in its declaration.
It is possible to make an exception by implementing your own NSImageRep subclass that copies on write. But I'm concerned with the default behavior. And accessing an Apple-supplied image from a singleton instance of an Apple-supplied class, where the image source should be a read-only ICNS file, is the closest example I can think of a default immutable NSImage.
Hmm. The one thing I didn't check is the image caching. That could still be uncopied, as it should only be updated when the image changes. But that's relatively short-lived data, anyways. The other thing would be vector graphics. The other possible exception is that -bitmapData forces the copy... I'll have to build up a few tests to check this out, but the Right thing to do, implementationwise, is to copy on -copy, especially when so much underbelly can be exposed.
I'm still rather confident that bitmaps can be treated as copied even to the pixel level, at least in terms of CPU load.
Scott Stevenson — Sep 29, 07 4664
Some people may do that, but the "proper" convention is to always copy value objects -- strings, numbers, etc.
With NSImage, you also need to consider how the object is originally created. You can use either -initByReferencingFile: or -initWithContentsOfFile:. Quoth the documentation for the referencing version:
"This method initializes the image object lazily. It does not actually open the specified file or create any image representations from its data until an application attempts to draw the image or request information about it."
In terms of the bitmapData property, you're right. That's as low as it goes, and with good reason. You can actually walk that memory buffer and change the bitmap data, pixel by pixel.
The other possible exception is that -bitmapData forces the copy
Possible. I don't know.
smat — Oct 31, 07 4917
>> You can even add Core Animation effects visually from IB
I am really curious how that works, I played around but didnt have much time, nor success.