November 21, 2005

Frameworks are Teh Suck, Err.

abstract

Apple's shared frameworks are very useful for sharing executable code and its associated resources among multiple applications, but were historically not designed to be created by authors of consumer applications. I discourage developers from creating frameworks as a method of sharing code, because they encourage code bloat, increase launch times, complicate the developer's fix/compile/link/debug cycle, and require extra effort in setting up correct and useful developer and deployment builds.


article

The Origins of Shared Frameworks on NeXTstep

It will help us to understand the limitations of shared frameworks if we examine the prevailing conditions for the time when they were created on NeXTstep. The user-base of NeXT machines was largely businesses and schools; institutions which generally had a knowledgeable system administrator in charge of clusters of machines and which typically ran suites of custom applications; consumer software for the NeXT was not as common. The net was not as broadly adopted, so application patches were largely unheard of; bug fixes and new versions were relegated to major releases.

Application installation in those days was done by the Installer, which could install resources in different directories throughout the disk, and left a record ("receipt") of what it had done so the installations could be reversed. Many sites also had a server machine vending a shared disk of applications and resources, so application installation only had to be done once.

Disk space was much more expensive, as was RAM. Any way to minimize the use of both was a huge win.

Shared frameworks were created by NeXT (and many others at the time) to allow multiple applications that need to use common code (eg, window handling or graphics drawing code) to link against a single binary, and thus even when, say, ten applications are running that use graphics, only a single version of NeXT's graphics drawing code has be to physically in memory.

NeXT's take on shared frameworks was more clever than most, in that frameworks took the form of directories, containing the code and its associated resources: localization files, images, sounds, and interface descriptions (NIBs). This provided a very convenient encapsulation of shared system resources (although there weren't provisions for multiple applications sharing a single copy of these).

Initially NeXT kept shared framework creation to themselves, but in a later release they allowed third-party developers to create them as well. For developers of custom applications for businesses, this was a godsend, as typically custom applications come in suites, and have a ton of shared code. For instance, at AT&T Wireless (an early NeXT adopter), they might have an application where they can look up the last call a subscriber made, and another application where they can change a subscriber's rate plan. The basic code to look up and display subscribers could now be shared between the two applications, which saves on disk space and physical memory when the program is run, and provided an easy way to re-use code and resources in multiple applications for developers.

The distinction between the two functions is important to make, because almost all third-party developers now take advantage of only the second benefit when they create their own shared frameworks, and the crux of my argument is that shared frameworks are a relatively inefficient way to accomplish this one result.

In order to benefit from the savings in disk space and physical memory in an installation, an end-user need two critical things: she needs to have installed two applications from a single vendor, and she needs to have installed the frameworks associated with those applications in a shared folder (typically, /Library/Frameworks/), so that all the applications know where to look for them.

This was not a problem when applications were installed with the Installer, because the Installer could, as stated, put files in multiple directories throughout the system. However, the trend in consumer applications (started by Omni, and rewarded with one of our first Apple Design Awards) became to have simple drag-and-drop installation of the application to wherever the user chose, which precluded installing frameworks in a well-known shared folder.

But not only did application creators who had a suite of applications that all used the same frameworks not know where the user might install those applications, they also didn't know which applications might be installed, so all "shared" frameworks had to be bundled inside even the smallest of applications.

This is the case today with Omni's applications; if you look inside the application wrapper (control-click on an application, and select "Show package contents") you'll find a Contents/Frameworks folder with copies of all relevant Omni frameworks in every Omni application you own.

Thus, there is no space savings from third-party frameworks, either in RAM or disk space.


Difficulties for Developers

But, the situation is worse than this. Frameworks are made of position-independent code, so they can be relocated in memory when linked against any arbitrary client application. This code is larger and slower than non-position-independent code, AND requires a quick fix-up at run-time when the client application launches. This fix-up time can become quite lengthy if there are lots of frameworks with lots of symbols used by any given application; in the old days Omni applications would spend many seconds loading their frameworks on launch.

[I don't mean to keep picking on Omni, but since I had a big hand in creating their open source frameworks, which are one of the largest and most popular collections of open source Cocoa code out there, I know details of the problems we encountered, and that I solved by giving up on frameworks.]

This can be ameliorated by creating frameworks at a fixed location, but you have to (a) read a bunch to understand how to do this, (b) make sure no two of your frameworks overlap, and you don't overlap anyone else's third-party frameworks that you might use, and (c) set up your build system to do it. This was actually a huge hassle at Omni; I was on the team that tried to streamline the process and it's still not something that is easily grasped by newcomers to coding.

But the situation is worse than that, because even after an application loads a framework into the right place in memory, the application has to adjust all its own symbols to point to the correct places in the framework. Luckily, Cocoa handles all of this for you, but unluckily, it takes time.

Again, this can be ameliorated by prebinding against the frameworks to which you've already assigned a fixed address (from above). Again, this is kind of a complicated process, and you spend a bunch of time learning nm and other tools trying to figure out if your application is "correctly prebound" with the frameworks.

But, it gets worse. When developing, your application probably does NOT want to prebind against the frameworks, because prebinding takes extra time in the link cycle. So, you have more setup in Xcode to sometimes prebind and sometimes not.

These are just the problems and slowdowns with loading frameworks at run time. There are also myriad problems in having your source code split up into several projects in Xcode (eg, a client application project and a framework project).

For instance, you probably have some build settings you want to enforce on your project; you like to debug with optimization level -O1, but you like to deploy with -Os like Apple recommends this week. Well, you'll have to copy those settings to every Xcode project for every framework you have. And make sure they stay updated.

Does this sound like duplicated code? The thing I hate most in the world? Yes, yes it does.

Also, you need to make sure when you're doing a development build that you link against the development versions of the framework you built in your development directory (because it's a pain to copy in the enormous with-symbols versions of the frameworks into your application every time you do a debug build), but you also need to make sure your deployment rules correctly do copy the frameworks into the client application's wrapper, or the app won't run. So, you get to write a bunch more Xcode configuration code, and, hey, you get to copy it into every application you write. And, oh boy, if you update it one place, be sure to remember to update it everywhere. (I believe the very latest Xcode has shared settings to help this situation, but you still have to write the darn configuration code.)

And, you need to make darn sure you don't confuse which versions of the frameworks you are linked against at any one time; eg, if you make a special debug build of the frameworks with some odd options, then you debug one of your other applications which use the frameworks, you'll suddenly have some very odd behaviors. (This happens more than one might imagine.)

And, when you do a deployment build, you want to make sure you strip the headers from your frameworks, as well as any subversion files. Yes, you get to write more Xcode configuration code. And copy it around to all your applications. Oh, boy.


Difficulties for End-Users

Now, why are you creating shared frameworks again? Because you want to re-use code in multiple projects. This is a noble goal. However, frameworks make it too easy to just throw every dang class that might be useful into them, so the developer forgets to ever prune old files that are no longer used at all. Because, if you have multiple framework projects and multiple application projects which use them, and you wonder if any particular framework class is used, you have to search through all of these projects for references. At Omni, this was forty-something projects to open; just opening them all took minutes, let alone searching them.

So you end up with a lot of extra code in your application that none of you applications still use. How do I feel about extra code?

But also, even worse, you end up linking in a lot of extra code that some applications use, but not this application. Because, unlike a standard library, there's no such thing as partially including a shared framework; you either grab all of its functionality or none.

How bad of a problem is this? Well, consider OmniDictionary. It connects to the network, downloads a definition from a dictionary server, displays the HTML. Simple. It uses some of the classes from the Omni frameworks to do this, but not nearly all of them.

Still, it has to include ALL of the code from any framework it touches, and ALL of the associated resources (image files, NIBs, etc), and ALL of the frameworks which that framework uses, as well.

With OmniDictionary, the frameworks it bundles with take up 1.6 megabytes. The actual application takes up 448 kilobytes. The application takes up four times as much space because of the frameworks.


The Alternatives for Code Re-use

Download and install subversion, and store all your source code in it, religiously.

Create a folder in your source code repository for each of your applications, and a folder for shared code and resources. In each project, in Xcode, drag only the files you really need into your project, and tell Xcode not to copy them into the project directory, and instead refer to them relative to the source directory.

Removing dead code from your shared folder is easy; at the worst you can just delete the files and do a build of your applications, and if the build succeeds you're not using them. Or you can open only your applications' projects (because what were your 'frameworks' now don't have projects associated with them) and search for the code, because your source files will never have any header imports of the form "#import "; they will have each file imported separately, and thus listed out for you to review and remove. (Conversely, if you decide to sunset a particular piece of code, it's very easy to find where it is referenced and rewrite the code. This happened recently to me when 10.4's NSXMLNode replaced my custom XML reading and writing classes.)

You don't spend any time configuring the frameworks' build environment because there isn't one. You don't spend any time setting up your frameworks' header file (eg, OmniAppKit.h) because there isn't one. You don't worry about whether your framework is pre-bound or position-independed because it doesn't exist.

What are the drawbacks? Well, when you include a source file in your application from your shared directory, you'll have to pay attention to which NIBs and images the files requires from the shared directory, and drag those into your application yourself. I think this is actually kind of good, because it also makes it possible to sunset images and NIBs. And, if you forget to drag in an image or NIB initially, it's an error you'll find immediately, the fix is easy, and it only needs to be done once. Thus, this isn't a problem that needs a complex solution.

Of course, if you have multiple frameworks, you might create a separate shared source directory for each one just to conceptually organize them. Or, keep them in subfolders. Whatever you like.

Note that subversion makes it very easy to modify your shared code for one project and not worry about affecting other projects; you can branch your top-level directory for any given project in subversion, and it effectively creates a copy-on-write version of that project, so you don't burn your entire source disk with a thousand versions of all your frameworks. When you're happy with a project, you can merge it back to the head (with the shared code changes) and check at _that time_ that your other applications like your newer and hopefully improved shared classes.

This brings up another issue, which is that with only one project per application it's much easier to associate a single tag with any given build, and then if a user or beta-tester encounters bugs you can go back to that version of the your source code with a single command. The problem with frameworks is it is too easy to ship different versions of the frameworks with any given build, so you end up reporting all your framework versions to the user to mention in bug reports, which is just another thing for the developer to have to check, and another avenue for error.

To get around this, developers with frameworks will write scripts to update their frameworks in a clean place and do a brand new build, but then those scripts have to be maintained by someone, and developers have to be educated about a particular site's practices. For instance, at Omni, only a few people in know how to do a beta build of a particular piece of software (not including many of the developers, but including the support personnel), so the beta process can be entirely gated by the availability of the support team.

In my alternative system, creating a beta build is as easy as opening the Xcode project, updating (inside Xcode), changing the target to "deployment", cleaning, and building. These steps are well-known to any developer, as they are all the same (except one) as during development.


Who Should Create Frameworks

Apple should, for one; because their frameworks have static base addresses, and because we all link against them at compile time, we don't suffer the same overhead by default that we do for third-party frameworks. Further, because every application is going to use, say, AppKit, and AppKit is installed in a known location, Apple's frameworks are correctly shared and result in saved RAM and saved disk space.

Companies writing suites of custom software, where they can use an Installer package and write the frameworks in a standard location, are also encouraged to use frameworks for the same reasons that Apple is.


summary

Creating shared frameworks is a lot of hassle for third-party developers of consumer software, introduces instability into the development process, and encourages slower and larger applications. Code sharing is better accomplished through creating new directories for shared code in subversion and judiciously including only the files and resources needed by any application in its Xcode project.


finis

Irony and sarcasm do not translate well onto the web. The title of this article and the previous Unit testing is teh suck, Urr. (sic) are references to the teachings of the Mooninites Ignignokt (who speaks in a sarcastic singsong and flips off the entire earth as hard as he can; "The pain is excruciating, but it's worth it") and Err (who is the Beavis to Ignignokt's Butthead).

The Mooninites are know-it-alls who come from a land where everything is better than here on earth, and they are far superior to us in every way. They pity us and our pathetic three dimensions, because on the moon they have five...

Err: THOUSAND!

Yes, five THOUSAND dimensions. Don't question it.

Labels:

27 Comments:

Anonymous Anonymous said...

I did once use a framework (included, Omni-like, in the application bundle) to obey an open-source license, that required that a library be replaceable. Seemed like an easy way to do so. Perhaps only because I was familiar with frameworks -- I think I've seen people do something similar with .dylib files.

November 21, 2005 12:46 PM

 
Anonymous charles said...

Wil, this article is really good, very clear and contains a lot of excellent information, and you make a very convincing case. Thanks!

I alsot want to say it is unfair to compare it to your 'unit testing' entry, because you know you were exagerating on that one, right? I don't think you then made such a strong case against unit testing.

Finally, I want also to say there might be another case where frameworks might make sense: when you want to share a piece of code with the community, and maybe gain from it too by making it LPGL or something equivalent. You don't want to necessarily share the whole app, but you probably want to use the framework itself rather than incorporating the source code in the app. However, I guess that you can then use the source code and build it within the app, though you might break things a little bit. Open source framework in a commercial app... OK, maybe not that frequent, but it happens... I am using one right now.

November 21, 2005 12:46 PM

 
Anonymous Dan Wood said...

One reason to have a framework is if your app has an SDK. If you want people to be able to write plug-ins to access certain classes in your app, it's nice to have a framework that the classes can just link to. This is how I did it in Watson and how we're doing it in Sandvox. Maybe there *is* a way to do it and I'm just a N00B ... especially compared to Wil.

November 21, 2005 1:04 PM

 
Anonymous nibs said...

the "SharedFrameworks" directory in a bundle is supposed to resolve both the issue of multiple copies of the same "bundled" framework in ram; as well as allowing applications to use the latest version of a SharedFramework when multiple compatible versions exist across several application bundles. this is an area where apple has failed to deliver (as of yet) what was once promised. if apple ever gets around to delivering on this promise (and their track record isn't horrendous in this regard) that problem will be solved.

also, the entire framework need not be loaded into the application that links against it. this is a space vs speed tradeoff that apple has made by passing in -single_module as a linker flag. if -multi-module is used, then only the modules referenced in an application will be loaded from a framework, it simply causes a bit more cross module glue code to be used when calling functions across modules within a framework. so it's only space on disk that needs be wasted with frameworks.

using svn to maintain these pseudo-shared libs sounds nice; however, the perpetual maintanence cost seem overwhelming. having to add entire chains of files and nibs because a pre-existing class has been augmented with functionality implemented in a network of other classes and nibs; and thus all projects need to be updated: this is alot of redundant work that frameworks solve automatically.
additionally, the frameworks only need be compiled once; in contrast every project is now recompiling it's own copy of your pseudo-svn frameworks. you would almost be better off creating a shared archive which would then allow only the code modules actually used by the app within a "framework" to be linked into each application. the source is still only compiled one time, but you still need to manage the nibs independently.

November 21, 2005 1:22 PM

 
Anonymous Mark Grimes said...

Wil, I'm curious as to your subversion stance on single versus multiple svn repos. It would seem with all the shared code maintained ancillary to your core projects that you must side the global repo, where your revision numbers are all across the board (albeit no technical impact, but semantically disgusting when you think in terms of revs). There seems to be no hard stance either way in terms of repo control other then using one per project makes it more difficult to share -- and often it is difficult to crystal ball gaze your repo map ahead of time. It's the mystery question of any version control documentation -- the layout.

Your article is well said as more detail from your comments at Adler, but has me thinking more about repository management then when I use frameworks.
Albeit you point out many important house-keeping points, I still question that if your frameworks were sized to not cross functional boundaries rather then arbitrary support methods (the goodie bag of useful code snippets), you have less of a problem worrying about unused code in your frameworks across application boundaries.

November 21, 2005 1:32 PM

 
Anonymous Seth Willits said...

Hear hear!

November 21, 2005 1:33 PM

 
Anonymous Daniel Jalkut said...

Thanks for posting this. You make some real good points that are common sense, and it helps to put my own habits into perspective. I have avoided using internal frameworks precisely for the "code bloat" reason.

However, I find it somewhat difficult to manage the "external references" aspect of this. Instead of using a single top-level subversion repository for my sources, I use a separate repository for each project. I suppose the wisdom of this might be debatable, but I liked the idea of, for instance, being able to dump and restore a repository in a more focused scope than "everything I've ever written." The fact that a project depends on source code outside of its repository is a major weakness of my system, and I need to address it. Mainly, I run the risk of missing some depended upon code when I make a logical tag on a project's sources.

While writing this comment, I've come up with the idea that might be a good solution. If I add a text file at the top-level of my projects that keeps track of external dependencies, I could enforce the required tagging on those dependent repositories.

I could get in the habit of using a shell tool for tagging that would automatically look in the dependent source trees and tag their repositories as well.

I'm curious if anybody has dealt with this is an ingenious way that they'd like to share. Or perhaps you'd like to convince me to use a single shared repository!

November 21, 2005 1:33 PM

 
Blogger Wil Shipley said...

Nibs:

Compile times are actually a lot better under my scheme; if you have to recompile all your frameworks from scratch (which is pretty common, because cross-framework dependency checking is unreliable) you compile a lot of useless classes.

Also, seriously, compiling any given file takes less than a second.

November 21, 2005 2:53 PM

 
Anonymous Henry said...

I suppose I agree with part of this; coders have a tendency to spend too much time trying to avoid any code duplication whatsoever by making for a shared library when just compiling the same thing twice would probably be more efficient.

But I'm reasonably certain a bunch of this information is out of date. Pre-binding was made less important in 10.3.4 and completely useless in 10.4. You probably shouldn't even bother nowadays. Xcode 2 also made the build configuration mess less worrisome; you can just drop a framework project into your app project, make the app dependent on the framework, and it will compile both with the build type you asked for.

There are other good uses for frameworks, too. If you want to, say make both a QuickTime plugin and a designated viewer app for your file format, you can have both the QT plugin and the viewer link to the same framework. Plus, when someone wants to upgrade, they can just drop a new framework in, and both apps get updated.

November 21, 2005 4:13 PM

 
Anonymous charles said...

From the point of view of the average user, it might however be easier to update 2 apps than to update a framework.

Having everything in one bundle definitely makes installation easier and should reassure the user.

November 21, 2005 4:43 PM

 
Blogger Alberto said...

I am not sure I totally agree with this. While developing frameworks for OS X is indeed teh suck, the goal of a framework (a.k.a. a library) is to encapsulate a group of related code and resources so that it is as easy to use as an object. This, to me, means that 'user' frameworks should be small, focused, and easy to use.

I think the real issue here is that LARGE frameworks are simply poorly organized and tend to include too much functionality for the sake of completeness, etc. Which from my perspective is scary because the larger the framework, the more the bugs that it brings to the party. This also makes it hard to use (install and deploy for both user and developer, etc). [to be balanced, small projects have the problem of name spaces, and if not carefully designed, can have interdependencies between them, making it just as bad or worse than a single large framework].

I think that frameworks should be small (and numerous) and be statically linked with my app. This enables streamlining what kinds of stuff I am adding to my app, while providing a nice packaging without running into all the installation hassles that a proper framework brings with.

In the NeXT days this was fairly easy to do (easier than today). As any project could be made a 'sub' project. So Wil's idea to use subversion (rcs and cvs in those days) as a way of pulling things worked mostly fine. Things were statically linked and as a bonus, ProjectBuilder allowed me to look at the 'sub' project without all the other peripheral noise. So yes, we had and ate subprojects for breakfast, lunch and dinner.

It would be great if XCode would support subprojects (you can do something similar with dependencies, but it is buggy and doesn't work right with all revs of the IDE (haven't checked this latest rev).

November 21, 2005 6:12 PM

 
Blogger Jon Hendry said...

Nowadays, instead of requiring an Installer, perhaps developers could provide an optional GUI Automator thingy which, when run, would move the appropriateframeworks to a shared location. Perhaps it would also tweak some flags somewhere so that later upgrades would know what the deal was on the user's machine, so they could automatically offer to do the same.

So if you got a second application from the vendor, you could opt to run the action, and you'd get the RAM/Disk-saving benefits.

But if you only had one app, or didn't care, you could use drag'n'drop.

Of course, this all depends on whether or not you could move the frameworks without breaking the application.

November 21, 2005 7:51 PM

 
Blogger Jon Hendry said...

Another comment: some of the problems cited are exacerbated by putting 'hot' code in a framework - code that is undergoing lots of changes and debugging.

Code that is stable and boring er, I mean mature, doesn't change that often, so using frameworks comprising such code should be much easier.

November 21, 2005 8:05 PM

 
Anonymous jas said...

Remember: deleted code is debugged code.

November 21, 2005 9:10 PM

 
Anonymous Anonymous said...

Most (well, all) of the frameworks I use are pre-made for me. E.g. the Omni frameworks: I compiled them once, and now I won't touch them anymore.
The thought of finding out which classes I should have to copy out of the frameworks and which nibs I would have to include makes me shudder. I wouldn't build my own framework, though: not unless I had to (e.g. to enable others to build plugins for my app).

The thing, IMHO, that really sucks, is when people publish frameworks, and then change the external inteface _without_ changing the framework version (A/B etc.) in a later version. Apple does that, and it really annoys me. I cannot use Mail from 10.3 on 10.4, since they changed some (undocumented) function in a framework, and didn't change the framework version.

November 22, 2005 12:59 AM

 
Anonymous Jack said...

Hear, hear! Back in the day, developing suites of business apps on NeXTStep, putting shared code in shared frameworks was da bomb. For most standalone applications however, they are indeed teh suck IMHO.

As others have suggested here, one problem is that they tend to be bloated; I used to use OmniNetworking, and found that while it was good code, there was just too much in it (and the other Omni frameworks it was dependent on) that was completely unused in my app, just contributing to useless binary bloat.

As far as the SDK aspect: IMHO a "better" solution, at least for simple cases such as a plugin system, is to export some headers containing objective-c protocols defining what the plugins need to implement, and what they can access from the app. No need to worry about maintaining frameworks then, plus you're free to completely rewrite your classes and still maintain plugin compatibility as long as you keep the same interfaces in your protocols.

November 22, 2005 3:52 AM

 
Anonymous cjwl said...

I finally got around to watching the Adler video and was amused at the exchange between Gus and Wil over frameworks. I have to agree with Wil, for a standalone app, frameworks are pointless. Even if you are shipping twos apps with completely common code, at least look into static linking. Also consider merging the two apps together if they have so much in common.

The issue is really organization of code. I can understand why people use Frameworks to organize code, it's easy. I do it myself, fortunately I work on a suite, so am exempt from Wil's wrath :). But, for a long time now, I have been wanting a tool which is like the Java class loader at link time. It would pull out all the classes and resources your app needs from a framework and statically link them in. Of course such a tool would have to be pretty smart, but it's not impossible. I may work on a suite, but there are certain apps in the suite which I want to be able to package up standalone, without the frameworks, so such a tool would be really handy. I'm not sure I am crazy about Wil's solution using Subversion, but I'll give it a shot and see how it works for me.

As to Dan Wood's comments, I think it's a great idea to have an SDK. I don't think exposing an Objective-C framework is the way to do it though. Go all the way and embed a scripting system in your app. More people will use it and it is easier to formalize the API. Of course it's a lot more work, but it is so much better IMO. The number of people that will use scripting is much larger than the number who will use Objective-C frameworks. If you're really fixated on use ObjC, you can do the whole API with protocols to avoid using a framework. This is what I have done in the past, it makes revising internals much easier, as there is a less ambiguity for people to use your stuff in unintended ways.

November 22, 2005 5:01 AM

 
Anonymous Anonymous said...

Oh, no!

It used to be that the greatest fear of adults in America was getting audited by the IRS. More recently, it had become getting shipped off the Guantanamo Bay for secret detention.

Now, it has become getting an Official Wil Shipley "Teh Suck" Designation thrown your way! ARRRRRGGHH!

November 22, 2005 5:44 AM

 
Anonymous Anonymous said...

Wil, by a coincidence I saw your comments here simultaneously with the Adler video.
I agree frameworks are a great thing for the system, not so great for non-Apple applications.
In fact, unless your shared code also includes resources (icons or whatever) it'd be better to put it into a static library and link that into each app; there'd still be all the niceties of sharing code either between apps or with the community without the hassle of having extra folders and dynamic loading.

November 22, 2005 9:16 AM

 
Anonymous Anonymous said...

Wil, by a coincidence I saw your comments here simultaneously with the Adler video.
I agree frameworks are a great thing for the system, not so great for non-Apple applications.
In fact, unless your shared code also includes resources (icons or whatever) it'd be better to put it into a static library and link that into each app; there'd still be all the niceties of sharing code either between apps or with the community without the hassle of having extra folders and dynamic loading.

November 22, 2005 9:16 AM

 
Anonymous Shawn Erickson said...

You may want to look at using .xcconfig files to provide a simple way of sharing configuration between multiple Xcode projects (see the Xcode documentation [1]). Using these I believe you can avoid one complaint you put forward.

I also wonder how applicable the load time issue is since the implements made to launch time binding in 10.3(.9 I believe). Those few seconds a couple of years ago likely are much much shorter as a result of the changes made.

[1] http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide21/Contents/Resources/en.lproj/05_05_build_configs/chapter_32_section_6.html

November 22, 2005 9:22 AM

 
Anonymous sea_dragons said...

Would someone kindly mention why one would want to deploy -Os? Is size such a big deal? Don't more care about performance?

Thanks in advance for the remedial lesson :-)

November 22, 2005 10:17 AM

 
Blogger harveyswik said...

sea_dragon:
It's been shown that for most cases -Os is the best possible scenario. Why? Locality. The improvements from -O2 to -O3 are small when compared to the actual performance if that extra code needs to be paged from disk.

If you consider that you're definitely not the only app running on the system at any given time then consider this: "What would it be like if everyone were as selfish as me."

It's been said that Apple and RedHat compile with -Os.

November 22, 2005 3:50 PM

 
Blogger Dethe Elza said...

For folks wondering whether it's better to use separate Subversion repositories or a single repository, that's a non-issue. Subversion can have external dependencies and pull the latest from a different repository quite easily.

I will put forward one more reason to like Frameworks. While I agree with what Wil said in general (and have argued similarly against shared libraries on other platforms), I am using Python more than Objective-C to access Cocoa, and the PyObjC bridge makes it trivial to import a framework and expose it for scripting. So one of the easiest ways to wrap C or ObjC code is to package it up as ObjC classes in a framework.

This is great for small, focused bits of functionality that Apple hasn't chosen to expose yet. I used it to package a 3rd party wrapper around the Sequence Grabber APIs for PySight, Python access to the iSight. I wouldn't recommend big, monolithic frameworks, but then I don't really need them. Most of what I can't get from AppKit I can get from the Python standard library (networking, XML processing, and much more.)

I like the new website look, Wil.

November 24, 2005 9:56 PM

 
Anonymous compactable said...

Here's a silly question - isn't this mainly flagging "it's bad to bundle frameworks in apps" ?

If the frameworks / libs were in fact central they would be shared which is how they were intended ... the "OS X way" (drag teh .app to install) conflicts with this way of doing things, which causes grief, but it doesn't necessarily mean a labelling of teh suck, no ?

Obviously using frameworks as intended can cause 'dll hell', and the dance of the thousand pre-requisites, and so are not perfect, but they can facilitate reuse if done well.

... I personally like the OS X way of installing, and think that the article does flag something really silly / slow / unnecessary in a lot of applications out there, but I do think frameworks have their place - outside the .app ...

November 28, 2005 11:39 AM

 
Anonymous Anonymous said...

"I had a big hand in creating their open source frameworks, which are one of the largest and most popular collections of open source Cocoa code out there"

Please ... Yes, plenty of things you did at OmniGroup where great and you are very much appreciated for that (really).

But that the Omni open source frameworks are popular collections of open source Cocoa code is just ridiculous. "keep it real!" ;-)

Amazingly there are basically no popular ThirdParty frameworks for OSX. There is a surprisingly huge amount of code duplication between Cocoa developers (everyone has his own isEmpty() and Foundation-Extension categories).

BTW: the one which was once popular, MiscKit, is a prime example what can be done better with your Svn approach (only mixin the "misc" code you actually need).

December 14, 2005 4:28 PM

 
Blogger Wil Shipley said...

"Keep it real": I'm not sure how you measure popularity. Certainly while I was there I heard of a lot of people using our frameworks, but I can't provide numbers. There are, undoubtedly, more popular frameworks in the world, but I don't know if there are more popular open source Cocoa frameworks.

December 14, 2005 4:52 PM

 

Post a Comment

<< Home