Here are two structure typedefs:
typedef struct {
BOOL b;
int i;
BOOL b2;
int i2;
BOOL b3;
int i3;
long l;
} unsorted_t;
typedef struct {
long l;
int i;
int i2;
int i3;
BOOL b;
BOOL b2;
BOOL b3;
} sorted_t;
Test question: what’s the difference between those two, aside from the different member order?
The correct answer is: The first one takes up 8 more bytes - 32 vs 24 on 64-bit computer, 28 vs 20 on a 32-bit. Why? Memory alignment. The memory access has to be aligned and when you mingle one-byte and 4-byte members, a lot of memory padding, i.e. unused memory is used.
So what’s the conclusion? When declaring structures, try moving pointers and anything larger to the top of the structure and move the tiny data types to the back. I know it’s just 8 bytes, but it can be more for larger structs and when you have thousands of those allocated, it can make up quite some memory. The only exception can be moving the most used member to the top as you’d be saving instructions - accessing a struct member consists of adding an offset to the struct address and then retrieving. As the first member is at offset 0, no additional computing is done.
I have worked hard on making the slideshow much better! It is now even with prices. Check it out:
This blog post is sponsored by Fuel Collective, LLC., makers of such great apps as Permute, Pochade, Snippet or Eon.
Today, I’m going to talk about localization in Cocoa and the way I have approached it. Cocoa has been designed since its very beginning to be multilingual – already back in the 90s, but much hasn’t been done about it since.
I’ve found a few ways to make localization of your apps a little easier. Localization is mostly about keeping all the files in sync (language-wise) and about not using literal strings in your code (plain @“string”).
Cocoa comes with a function NSLocalizedStringFromTable, which resolves which language to use and loads the localized string from a strings file inside your app. It’s pretty easy, but it’s a real pain to type the name of the table over and over again, also the function takes three arguments, the third one is the default string value which is used if the phrase couldn’t be found in the strings file. Most of us have just one strings file per app, typically called Localizable.strings. It’s hence quite useful to define a macro like this:
Ok. These are strings in your code. What about UI? This is what’s painful. Keeping all the XIB files in sync is almost impossible. So I’ve taken the liberty of writing a few localization categories to help me with this.
The general idea is that all UI strings are kept in the Localizable.strings file as well. Whenever you load a XIB file with a view or a window, all you have to do is call [loadedView localizeView] (or [[loadedWindow contentView] localizeView]). That’s it!
What about the MainMenu.xib – you don’t load that one programmatically – just in your app’s delegate/controller, add this code [[NSApp mainMenu] localizeMenu]; to the awakeFromNib method. Plus call the -localizeView method on any views that were loaded as well. Pretty easy, huh?
So what’s the advantage? You only need to localize 1 (one!) file and it’s a simple text file, anyone can edit, without the need to install developer tools.
Are there disadvantages? Well, there’s a few minor ones – you need to remember to call the -localizeView or -localizeMenu methods on any loaded views (these methods work recursively, so only call this once on the main superview). The other one is a tiny overhead in going through all the subviews and changing their titles, etc. Right now, I’ve written support for NSButton, NSPopUpButton and NSTextField classes, writing support for more is quite easy and left up to you.
Here’s the source code: http://cl.ly/2p2y122g2K3s2h0v0P1S
P.S.: I keep #import “FCLocalizationSupport.h” in the prefix header – these methods are used very often, I recommend you to do the same.
This blog is sponsored by Fuel Collective, LLC. the creators of such cool apps as Permute, Pochade, Snippet and Eon.
It’s been a long time since I posted here last time and there’s many reasons to it, though the most obvious one is that I haven’t had any time. Literally – no time on my hands. As I’m unable to make sure updates to this blog would be regular, I’m (at least for now) not going to work on these lessons anymore. However, from time to time I’ll drop by to say hi and to write about some technique I’ve learned.
This time, I’d like to talk about memory efficiency. I’m sure there’s a lot of articles out there covering this topic in general, but not that many of those try to focus on Objective-C.
Computers currently tend to have more and more memory, faster CPUs, busses have greater bandwidth, etc. Do we really need to be memory efficient anymore? The answer is yes, we do. Remember that all of the data put into the memory has to be loaded from somewhere, it has to go through the CPU, making your app less efficient in general. Also, current operating systems tend to run more and more background processes, which also take up memory. I am always wondering, when I see my MBP with 4GB RAM to have 2GB swapped out – what so important is taking up 6GB of memory?! Just think about how much text this is, that it’s more than the size of most computers’ hard drives 10 years ago.
The question is what to do – how to be more memory-efficient. To answer that, we need to examine, what’s taking up most of your app’s memory. It’s usually data that you load from somewhere (cache, online data, etc.), mostly images, which can take up a lot of memory. With NSImages, always (unless it’s posing some performance issues), use the constructors that have “…ByReferencingFile:” or “…ByReferencingURL:” – don’t unnecessarily use the constructors that load the whole image into memory on init, as it may not be needed at all later on.
Next, think about what data do you really need to have in memory. It’s completely OK to store the data that you think might not be used for a while on the disk and then read it when needed. But note that all disk reads are in its core syscalls (system calls – special instructions that “ask” the kernel to do something – they require a context switch which takes about 100-200 instructions) and that the disks are always slower compared to memory. Just make sure only data that won’t be needed in the near future (say a minute+) is cached.
That’s about for the general advice, google for more if you’re interested, this can be applied to any programming language and as I’ve said, I want to focus on ObjC. The question here is how to store the data in memory. Use custom objects? NSDictionaries? Something else?
I’ve created a little experiment. Create an array and fill it with 100,000 objects which contain 5 strings that are generated (I was using NSString’s stringWithFormat and was passing current date divided by some random numbers), so that all of the pointers are unique.
First, I’ve used NSDictionaries to store the data. The process ended up roughly on 342MB of RAM.
Then I’ve created my own class, which had 5 NSString* properties which were assigned the same objects as the NSDictionaries were filled with. In my results the custom objects were a little more efficient, though not by much (from which you can see NSDictionary /or more likely CFDictionary/ is quite efficient when it comes to memory).
For the last test, I went low-level. No, not assembler low, just C-low. I created a struct, which had 6 char* pointers, into which I malloc’ed just enough memory so that the string would fit with a few char padding and I’ve wrapped the pointer to the struct in NSValue – voila, I was at 190MB. That’s almost just half the ObjC usage, right?
So what’s the conclusion? The more low-level you go, the better. Of course, it would be hard to write everything in C, that’s why there’s object-oriented programming, right? Just keep in mind that this C struct took up (on a 64-bit computer including the actual strings) just something over 120 bytes in theory – of course, as I was malloc’ing mostly short strings under 32 bytes, so I was wasting a lot of memory (as malloc usually will mark the whole 32 bytes as used up). Again, in theory, all the 100,000 items could fit into 10MB of RAM if I really wanted (would require some manual memory management). Yeah, I know, you think I’m insane proposing you should be allocating continuous pieces of memory and then dividing them into structs, but hey, in the times a computer had 1MB of RAM, this is how it was done.
The biggest disadvantage with the last solution really isn’t working with C-strings and structs – that’s not that hard, really. The issue here is comparing items and calling methods on them – it would require you to use a custom object that’s just a wrapper for a struct pointer – generally like NSValue is – providing all the interface methods, which isn’t that hard, really.
This blog is sponsored by Fuel Collective, LLC.
Table Tableau
Hello again and sorry for the delay! It’s been a busy month, in which I finally earned by Bachelor’s degree! Hurray!
In this lesson, we’ll cover a basic way to handle a tableview – the control that has rows and columns.
Let’s Create the Creator
Right now, your window in Interface Builder should look something like this:

And those buttons should be connected to the LTAnimalFarmApplicationDelegate. Just to make sure there isn’t any confusion, you do not need to make an IBOutlet for every single control, this was just to make you practice the IB connections.
Your LTAnimalFarmApplicationDelegate.h should look something like this:

All great. So let’s create a creator. We’ll be adding a table view to the window:

Now a little theory. What you really see, isn’t the NSTableView itself. NSTableView is the view that displays the rows and columns. NSScrollView is the view that’s around and allows the table view to be longer than the area in the window, letting you scroll up and down. NSScrollView can be used for any view – for example in TextEdit, the NSTextView, into which you’re typing is surrounded by NSScrollView as well. The headers are displayed via NSTableHeaderView. The scroll bars are NSScrollers.
Hold down shift and right-click on the table view – you’ll get a menu allowing you to select the Window – Content View – Scroll View – Table View – Table Column: select the table view. In properties, you can play around with how it should look, I will, however, go with Alternating rows and will only have 1 column, showing no headers.
You should end up with something like this:

Adding Items to Table View
There are two approaches to filling the table view with data. One is manually via data source protocol (this is what we’ll do), the other is via bindings, which is easier, faster, but less customizable and does a little ‘magic’ which doesn’t let you see how the table view works.
Each cell is drawn via a NSCell (most likely a subclass of NSCell). The NSTableView itself only draws the background – the lines, the highlight – and takes care of the layout. You can imagine that this is how it works: the table view draws the background, then asks its data source how many rows are there and for each row and column (thus for each cell) it tells a cell object to draw within a certain area that represents the cell.
Apple provides a few cells that you can use (NSTextFieldCell for text, NSImageView for images, NSButtonCell for checkboxes, etc.); or you can subclass the cell as you wish.
Create an outlet for a NSTableView in the LTAnimalFarmApplicationDelegate and link it in IB. Select the table view in IB (via the Shift-Right-Click) and right-click it – drag the dataSource outlet to the Animal Farm Application Delegate:

This tells the table view to inquire information about the data from the LTAnimalFarmApplicationDelegate.
This is all you need to do in IB now. Switch back to Xcode and add a variable to LTAnimalFarmApplicationDelegate – NSMutableArray *_animalKingdom. It’s a good practice to prefix all object variables with an underscore. NSMutableArray is a mutable instance of NSArray, which is a basic class for keeping lists of objects:

Now go to the implementation counterpart (the .m file) and add a –(id)init method. This is the standard method for object creation. It’s a custom that each init method looks like this:
–(id)init{
if (self = [super init]){
//Your own initializations
}
return self;
}
Weird, right? The first line assigns self to be [super init] – the superclass inits the instance, all the way back to NSObject. If there was an error in initialization, you get a nil, which is what’s the if statement testing for: “if the initialization of the super class went fine, do your own initializations, then return self”. Unlike many other languages, you do need to return self at the end. Some developers like an early-exit version:
–(id)init{
if ((self = [super init]) == nil){
return nil;
}
//Your own initializations
return self;
}
Use whichever you like. Within ‘Your own initializations’, you should create all instance variables – in our case animalKingdom = [[NSMutableArray array] retain]; (remember to retain it, as +array returns an autoreleased instance!). Or you can write it as animalKingdom = [[NSMutableArray alloc] init]; (do not retain this as -init returns an instance with retain count +1!).
Whenever you have instance variables that you create in the source code (not IBOutlets), you need to add a -dealloc method to release them when the object is destroyed so that your code isn’t leaking:
–(void)dealloc{
[_animalKingdom release];
[super dealloc];
}
Always remember to call [super dealloc] and never call -dealloc directly!
A little homework for you as always:
For each of the IBAction methods, create an animal of the right kind and add it to the NSMutableArray. See documentation for methods that are defined on NSMutableArray and NSArray. Remember that adding an object to an array retains it, so you should be passing an autoreleased object or releasing it afterwards.
E.g. for chicken:
–(IBAction)createChicken:(id)sender{
LTChicken *chicken = [[[LTChicken alloc] init] autorelease];
[_animalKingdom addObject:chicken];
}
Yeah, sorry about this. Been a little busy lately. The next lesson will come up in roughly 14 days. See you then!
This blog is sponsored by Fuel Collective, LLC.
Talk to the UI
In the next few lessons we’ll focus on the UI basics – e.g. how to load a NIB file, how to link controls to object variables, etc. For the first time today, you’ll also be able to download the project. If you’re having trouble with something, however, don’t hesitate and ask me, we’ll work it out, rather than you skipping a step. If you’re too shy to leave a comment here (or don’t want to), you can reach me at kvasa-@-me.com (without the dashes).
Main NIB
There’s a special NIB file in every app – the main NIB file that includes the menu bar and usually a window. Take a look at the main NIB file you’ve created last time:

Each NIB file has a File Owner – it’s an object that should take care of the NIB object, and have the objects linked. You’ll see later on how to use that.
First Responder is a shortcut to the currently focused control. E.g. if you have a button that should copy the text of currently selected text field, you just link it to the First Responder instead of testing which text field is selected and then copying the text.
Application is the NSApplication object – there’s just one NSApplication within the running application – it has a couple actions like showing the About window, quitting, etc.
Font Manager isn’t needed in every NIB – it’s a way to show the font panel, etc.
All of these items listed above can be called ‘special’ as they don’t get created when the NIB is instantiated (a technical term meaning the NIB was loaded) – they already existed when the NIB was loaded.
Our new NIB file also has a Main Menu and a Window – these do get created.
Application Delegate
When you create a new project in Xcode from the Cocoa Application template, it already has an application delegate. But as I wanted to make your life a little harder and we started with a command line tool, we need to build our way up to the UI and all the nifty things Xcode prepares for you.
Go to Xcode and right-click the Source group and choose Add > New File… (you can also use the File menu). Create a new ObjC class file called LTAnimalFarmApplicationDelegate.
In the header file add a variable:
IBOutlet NSWindow *_mainWindow;
and a method
-(IBAction)quit:(id)sender;
IBOutlet tells Interface Builder that you allow this variable to be linked to some control in the NIB, IBAction tells it that you allow an action to be linked to it. If you’re wondering what’s the (id)sender then it’s the control that sent the action – e.g. a NSButton if a button was pressed and fired the action.
Switch to the .m file and implement the quit method:
-(IBAction)quit:(id)sender{
[NSApp terminate:sender];
}
NSApp refers to the shared NSApplication object – use it freely anywhere. –[NSApplication terminate:] will quit the app.
Work in IB
Now we need to link it in IB. Switch to IB and open the Library window (under Tools menu) and find a NSObject object (use the search field to filter) and drag it into the MainMenu.xib window. When it’s added, we need to tell IB it’s not NSObject, but LTAnimalFarmApplicationDelegate. To do so, select the newly created object and select Identity tab in the Inspector (again, Tools menu) – under Class, enter LTAnimalFarmApplicationDelegate (it should autocomplete).
Right-click drag (like regular dragging but with the right-click or ctrl-click) the LTAnimalFarmApplicationDelegate and drag it to the Window – let go and choose the _mainWindow outlet. This links the variable to an actual object.
Open the Window and drag a NSButton object from the Library window onto the window:

Double-click the button and rename it to “Quit”. Again, right-click drag this time onto the LTAnimalFarmApplicationDelegate and choose the Quit action.
Go to Xcode, compile and run it. Now when you press the button, the app quits. Not much, but you know now how to link outlets and actions in IB.
Download Source
You can download the source code here: Lesson 5 Note that I have cleaned the folder from some files you don’t need in the UI application so don’t panic.
Homework
As always, some stuff for you to try out:
1) Remove the Quit button from the window and add one for each animal type you have (you should have Chicken, Cow, Horse Pig) and name it ‘Create —ANIMAL—’ (e.g. ‘Create a Cow’).
2) In LTAnimalFarmApplicationDelegate, add an IBAction and IBOutlet for each of the buttons and link them in IB.
Via http://blog.fuelcollective.com/
It’s on it’s way! But before it gets here, let’s talk about it (behind it’s back!). What has changed? Well, we completely redesigned Swatch to use a more “Mac Like”, cleaner, easier interface. There are now 6 ways to select the color you want, Loupe, CMYK Sliders, Color Wheel, HSB Sliders, RGB…
This blog is sponsored by FuelCollective, LLC.
You and I - UI.
As promised, today (and from today on) the main topic will be about the UI. Most of the guides out there try to start by creating a new application from the template. We’re not. It’s important to see how the UI works behind the scenes (not too far behind, though) works. So we’ll upgrade our AnimalFarm console app into a UI app.
Again, note that I’m using Xcode 3, whereas in future readers might be using Xcode 4 or later. Once you learn what’s what, it’s easy to find where’s what.
Targets
When the source code gets compiled, it results in some binary (typically). On OS X this can be an executable file (just one file that can be run in Terminal - that’s our AnimalFarm right now), an application bundle (the app’s really a folder with bunch of files), a plugin bundle, etc.
Even with the first type, you theoretically can display UI, however, it’s not something recommended. Here’s why: in the application bundle, you can store NIB files, which contain a serialized (don’t worry about this word right now) UI - windows, buttons, etc. When your app is just a binary file, there’s nowhere to put those files (you can load NIB files from outside the bundle, but let’s not make it too complicated).
So how do we tell Xcode to create a regular app bundle instead of just the binary file? Xcode has something called Targets. Right now, you have one target, which is now the binary file. In the condensed layout (see General preferences in Xcode), you can switch to the Targets tab - you should see the AnimalFarm target there - when you expand it, you can see it has a several “folders” - called Build Phases - each of them does something slightly different.
Right-click the AnimalFarm target and choose Delete. Now right-click the Targets folder, pick Add > New Target… and select Cocoa > Application. Call it AnimalFarm (again). An info panel should pop up. Here you can further on set some of the more advanced stuff like target OS, target CPU(s), etc. (under Build tab). Close it for now.
If you build the app right now, an empty application bundle is created. You won’t be able to launch it or anything. Why? What about the previous code? It’s not being compiled, because it’s not in the new app’s ‘Compile Sources’ build phase. Go to the Files tab, select all the .m files (don’t select AnimalFarm_Prefix.pch and .h files, though) and drag them onto the Targets tab (the tab view automatically switches) and drop them on the Compile Sources build phase.
Now run it. Voila! It runs and quits with whatever logs you previously had in there written on the console.
Where’s the UI? There it is!
You’re so unpatient… There’s no UI because how apps work is that they enter the main() function (where are your logs) and then they quit. So how do you create the UI? Delete all the code inside main() (even the NSAutoreleasePool code) and enter this line:
return NSApplicationMain(argc, argv);
That’s it. What this does is that it creates a shared NSApplication object and builds up the app’s runtime. When you run it now, the app fails with this message on console:
Unable to load nib file: MainMenu, exiting
MainMenu? Where did that come from? When you created a new target, a new file was created - AnimalFarm-Info.plist. This file gets processed and copied into the app bundle and has some information for NSApplication (and other classes) about how it should work. Open it. Go through the keys. Pay special attention to Bundle Identifier - you should change this to e.g. com.disobedient-cocoa.${PRODUCT_NAME:rfc1034identifier} - the weird strings starting with $ will get replaced when being processed, so it will result in something like com.disobedient-cocoa.AnimalFarm. What’s so special about this? Your app can be addressed by other apps by this string and also this is the name of the preference file for your app.
‘Main nib file base name’ - ha! MainMenu. This is a nib file’s name that gets loaded on start and should contain a menu bar, etc. So let’s create it.
Make sure you’re in the Files tab, right-click the AnimalFarm project (in the list), create a new group and call it ‘Resources’ (just to keep it organized). Right-click the newly created group and select Add > New File… - and you’ll want User Interface > Application XIB. Call is MainMenu and in the location field, add English.lproj to the path - OS X apps are localizable and it’s a custom to keep the XIB (or when compiled NIB) files in the language folders even if the app only uses one language.
Xcode might bitch about the folder not existing, just hit Create. OK, here you go, run the app! Yay a window! Mission accomplished.
Homerwork
Double-click MainMenu.xib to open it in Interface Builder and play around. Try adding controls to the window, etc. That’s it.