Skip to content

Archive

Category: iPhone/iTouch Programming

After almost a year, my third update to the ObjC beginner caveats blurb. 8 new caveats added today (marked with [NEW])

Language/SDK

1. NSArray/NSMutableArray cannot hold ints or NSInteger
>> although NSInteger is notationally similar to NSNumber, NSNumber is an object while NSInteger is an alias for int or long (depending on whether you’re running a 32/64 bits architecture). NSArray can only hold objects. If you want to add a number to an NSArray, use NSNumber and initialise your number with something like [NSNumber numberWithInt:26].
(Yes, you can use standard C arrays, there are quite a few posts about this around)

2. NSNumber doesn’t auto-unbox
>> If you try to assign NSNumber to an int (or, better, an NSInteger), you’re assigning a pointer, not the actual number. To get the actual number, use something like: [MyNSNumber integerValue]

3. Strings don’t concatenate with [+] or [.]
>>
If something like “Score: “+score is what you’re used to, try making friends with:
[NSString stringWithFormat:@"Score: %i", score];

4. In, (void)applicationDidFinishLaunching:(UIApplication *)application {…}not all IBOutlets depending on your nib file will initialize until your view is added to the main window
after [window makeKeyAndVisible]; it should be safe to access all IBOutlets attached to your viewController.

5. I updated the frame property of a subview, but the coordinates look incorrect.
>> after updating the UIView.frame property on a subview, invoke setNeedsLayout on the parent view.

6. NSTimer fires at the wrong time / fires too many times
>> When you allocate/init NSTimer with the usual code, you don’t need to invoke fire(). NSTimer is setup as soon as it’s initialized and fire() shouldn’t be called directly as it, *doh!* fires the timer.
>> Whatever you name your callback method, it should take a unique NSTimer argument ( the selector argument would typically look like @selector(myCallback:) with the semi-colon at the end).
What happened to me is that my timer kept firing over and over even though repeat:NO was set. Adding the timer argument to the callback fixed the problem.

7. You cannot declare new variables inside a switch statement

switch (foo) {

case BAR:

char foobar=’*'; // compile error

break;

}

Use this instead:

char foobar;

switch (foo) {

case BAR:

foobar=’*'; // OK

break;

}

Memory Management

8. Use NSZombieEnabled to crash and get a call stack when your program attempts accessing a deallocated object [NEW]

Google it…

9. You need a symbolic breakpoint to hit malloc_error_break and get a call stack [NEW]

Google it (I feel lazy).

10. Unless otherwise stated, objects allocated as a side effect of calling methods other than [alloc] are autoreleased.

This is especially applicable to objects created using factory methods. Take the following example:

[NSMutableArray arrayWithCapacity:5]; // will be released automatically

[[NSMutableArray alloc]initWithCapacity:5]; // we just created a zombie!

At first, it would seem that [NSMutableArray arrayWith...] forms are just shorthands for [[NSMutableArray alloc] initWith…]. Hell, not quite.

[NSMutableArray arrayWith...] and other, similar factory methods, ‘emulate stack allocation’ for reference types. This means that we don’t need to worry about releasing them, as the so-called autorelease pool will take care of them for us.

When we check our code for memory issues, knowing which objects are kept in memory (on the heap) is essential. One way to learn about these is to scan for alloc, retain and release statements. The so called ’shorthand forms’ allow using objects transiently, without worrying about memory issues, so this convention can help reduce the time spent on memory management.

There are downsides to this for unfortunate beginners:

(1) When we start with objective c, the [alloc[init form appears verbose and cumbersome. So we're likely to create our own shortcuts -- generating 'silent allocations' that make memory management harder.
(2) If we use the 'shorthand' forms, we quickly end up with weird, hard to fix bugs, because we might end up assigning auto-releaseable objects to variables, then these objects get deleted implicitly, and finally we end up accessing... ...garbage(!!!).

11. Beware of  abusing autorelease [NEW]

Autorelease is useful and in some cases you cannot avoid using it:

  • Objects returned by factory methods
    A(n essential) convention dictates that objects created using [alloc] have a reference count of 1. In contrast, callers of factory methods are not responsible for releasing returned objects unless they retain them (see #10)
    Since we can’t use [release] before returning an object we just created, we need to use [autorelease]
  • An object on the call stack may get deallocated if [release] is called.
    Now, it may be argued that only bad design can cause this to happen. Nevertheless one way to solve the problem (it can get nasty) is to use [autorelease]

Now that this is out of the way, beware of practices involving using [autorelease] as a ‘default safe way’. Here’s why:

If an object deallocates unexpectedly following a call to [autorelease] the call stack above [dealloc] doesn’t tell you what caused this object to deallocate.

I don’t see how a coding style involving loosing track of deallocation events can be safe.

12. You can crash the leaks tool in Instruments (seen in Instruments 4.0, 4.1) [NEW]

Recently I managed quirky memory management code that didn’t crash on device or in the simulator, yet crashed instruments. Checking the details, I stumbled on something like ‘invalid leaks data’.

I was about to use up one of my support tickets but reflected that sending my code over and waiting for the ticket to process would take a lot longer than reverting my changes and use the weak muscle to figure it out.

On the downside I got lucky before I managed to narrow it down.

Even if you’re not part of a team, consider using versioning (SVN or whatever new-fangled stuff you’d like).

Kind reminder:

No versioning
=> no diff tool
=> no way to accurately revert changes
=> panic
=> loss of money
=> loss of sleep
=> loss of hair(*)

(*)If you are bald I trust this won’t be an issue.

13. WTF my code crashes when ‘unplugged’ [NEW]

Consider the following case:

  • Your code doesn’t crash when debugging on-device.
  • Your code doesn’t crash when debugging in the simulator.
  • Your code crashes when running in the simulator after pressing the app icon.
  • Your code crashes on-device when running after pressing the app icon.

Then try this:

  • Disable NSZombieEnabled. Quite possibly you’ll see a fairly non-descript crash in the debugger when running the same code.
  • Try to isolate the stack that causes the crash (it’s not meant to be fun but using a dichotomy you might get it done in less than an hour)
  • Re-enable NSZombieEnabled. At this point you may see inconsistent variable assignments in the debug window.
  • Set breakpoints on [dealloc]. Quite possibly you’re deallocating an object that’s already ’somewhere up’ on the call stack. On sunny days this crashes the device/simulator (hey, it’s actually a GOOD thing). On rainy days it drives the debugger crazy.

Build errors & warnings

14. Warning: Multiple Build Commands for output file …

In XCode, the name of a resource (e.g. a picture to include in the build as resource) is different from the path the resource is retrieved from. Several resources can have the same name, linked with different paths. So for example we can have:

  • foo.jpg (/images/foo.jpg)
  • foo.jpg (/mypics/draft/foo.jpg)

In the final bundle, however these resources are in conflict, they both target /foo.jpg. XCode will issue a warning if resources conflict in this way.

Unsurprisingly, this typically happens when reorganizing project resources.

15. Linking C++ libraries [NEW]

If your project depends on C++/ObjC++ libraries, you may need to add -lstdc++ to other linker flags to your build (see here).

Nibbling UIs (Interface Builder)

16. Action mappings are one-to-many

Yesterday I copied a button from my UI and bound an action to it. Then I was rather puzzled to find that, when I clicked on this button, my game started off with an ominous GL error code. I thought binding an action to a button overrides the previously bound action. It doesn’t. The same user action on the same widget can bind several IBAction targets. In my case this caused the game’s start method to be called twice.

Asset management

17. Use the blue folders [NEW]

If you have hundreds of assets, adding them manually will be a pain. However you can link a whole folder; in XCode’s ‘add files wizard’ select your folder and tick create folder references automatically…

XCode is getting better at detecting changed/added assets between builds (but see #18, below)

18. Sometimes you need to remove your app from the simulator/test device [NEW]

If your code relies on a mechanism allowing to retrieve a resource from one of several locations, you need to delete your app from the simulator / device whenever you remove assets from a blue folder.

Let’s say your sound folder is organized like this:

default_sounds/
---- KO_sound.caf
---- goblin_sounds/
-------- KO_sound.caf

Now suppose you deleted KO_sound.caf under goblin_sounds. Well the goblin specific sound recorded from your little sister’s performance will still load and play because it doesn’t get removed automatically.

Between builds, no files are deleted from package contents. I don’t know whether it’s a bug or not. It’s often annoying.

Don’t retain anything unless you must

Regarding reference counting, this is the idea I’d like a developer to at least consider. For several reasons.

  • A dangling pointer / weak reference needn’t be evil. During development hitting a dangling pointer is better than preventing an object to deallocate when it should. An object that exceeds it’s intended lifetime can behave in undesirable, unpredictable ways. All it takes to detect an invalid object is turning NSZombieEnabled on.
  • Everything retained needs to be released. Retain less = less work.
  • If the sums don’t add up (over-released/over-retained object) it’s easier to work out what’s wrong when the number of objects involved is small (e.g. 1, 2 or 3)
  • Potentially any object that retains a target will increase the target’s lifetime; this a priori translates into increased memory usage.
  • Whenever retaining an object we risk creating a cyclic reference. Of course ‘we know what we’re doing’ (and cyclic dependencies can be removed) but isn’t it just easier to avoid getting too many of these.

Unwanted objects that remain inside the runtime after they should have deallocated will harm you. The more your system is dynamic (e.g. game, simulation) the more these objects are likely to generate functional bugs that are hard to figure.

I read a little about automated reference counting (ARC) which we are getting in iOS5. If I understand correctly (reading here) the central idea of this article will translate to ‘don’t abuse strong references’. Now that I more or less get it I look forward to using ARC but I guess I’ll be waiting for another 6 months or so, being a happy laggard.

A quick introduction

Reference counting approaches memory management indirectly, using concurrent ownership:

  • Take ownership of an object by retaining it
  • Relinquish ownership by releasing the object.
  • When all owners of an object have released it, the object is deallocated.

indirect : we don’t explicitly deallocate the object.
concurrent: several objects can simultaneously retain the same target.

The basic rules are covered in many places, like here and here and from the horse’s mouth, here.

Reference counting is efficient, error prone and occasionally awkward.

More efficient than garbage collection: objects get deallocated as soon as their reference count reaches zero, whereas GC is heuristic and may cause your program to slow down unexpectedly while it’s doing its thing.

Error prone – programmers need to pair release/retain statements (either directly or indirectly). Mismatched statements cause a program to leak or crash. Additionally reference counting is hackable; it is easy to traffic the sums (either accidentally or by design) and obtain a valid program that handles memory correctly, while violating reference counting rules.

Awkward, notably when we know beforehand that we would like to deallocate a well defined subset of the runtime graph. A typical example is when you start a kind of ’session’, allocate any number of objects in the course of the session and wish to deallocate all the objects at the end of the session. In such cases opting out may be somewhat short sighted yet remains attractive.

A design idea

There is a principle which I find rather productive: instead of thinking about whether an object should retain X or not, consider X then try to think about an object ‘up the runtime graph’ that should own X. Often there is an object Y such that, if Y deallocates, X should also deallocate. It could be the parent of X or maybe another object up the chain.

Now, if there is only one such object Y, then you don’t need to retain X anywhere else. You can even assert the retain count to ensure that X is unambiguously managed by Y.

Anti-patterns?

There are little recipes around (e.g. here and here) that you can use to ‘ease the pain of memory management’.  From the point of ownership these recipes work the same way GC does: easy way out of memory management issues, hard into functional bugs with all the enticing prospects of a muddle-through approach.

One point these approaches have in common is ‘if in doubt, retain’. I’m OK with that as long as I know (beyond reasonable doubt) that keeping the target alive won’t generate unwanted behavior. If the target is an observer that receives and processes notifications… …then if in doubt, don’t retain. A clean, happy crash will provide the decision point where you can say:

  • ‘Yea, this object should still be alive at this point’ (in which case maybe something else should have retained it) or…
  • ‘No, this object is dead and well dead, we should have sent a death note’

Additionally these approaches look incomplete. You need to use class extensions if you want to declare everything as a property without exposing all your ivars.

Weak references

An unretained field is a ‘weak reference’. At least in a first approach, the use of weak references is encouraged in a number of situations:

  • Backward references from a child to a parent
  • Listener sets. See a straightforward application here.
  • Same type objects cross-referencing each other.
  • Any situation where you feel unsure whether to claim ownership (retain) or not.

Implementation details

Maybe for historical reasons there are two approaches to enforcing reference counting in objective C:

  • The non intrusive approach revolves around tagging using properties and indirect access using self.x = . Although this approach looks theoretically better and safer there are practical details of how it is done in Objective C which I often find off-putting. For one I like to not declare properties until I want to expose public state, and I’m not used to class extensions, thus find myself unwilling to add class extensions to my .m files.
  • An older approach revolves around the [release] and [retain] statements. The advantage (easier reviewing/debugging) and inconvenience (intrusive approach leading to somewhat cluttered code) are the explicit way in which things are done. This leads to a weird situation because it makes it more likely that bugs are introduced while making the same bugs easier to fix.

Note about [autorelease]

[autorelease] is very convenient and helps avoid errors in many situations. Sadly enough when an error does occur and [autorelease] is the lucky guy that causes a target to deallocate, we get very little debugging information because [autorelease] doesn’t take effect until we exit the frame.

So I try to limit its usage to where it’s unavoidable.

What is covered elsewhere (or should be)

  • Cocoa collections (NSArray, NSSet, NSDictionary) retain all their elements. This can be a hindrance in some cases, but you can configure the underlying, toll-free bridged counterparts, as demonstrated here.
  • There are various approaches to notifying stakeholders when an object gets deallocated. I will try to write a quick article about an approach I find useful when implementing observer schemes.

Nothing’s perfect. XCode is kind of usable but there are ways it could be greatly improved. Instead of posting a rant, I have decided to structure my requests a little and share them with you.

__________________________________________________________________

If you like this article

You’re an XCode user. You agree that this stuff is important.
Feel free to paste this article on your blog and submit bug reports / enhancement requests.
Duplicates help developers understand what is important to their users.

__________________________________________________________________

1. XCode should have a feedback button in the Help menu

We are power users. We know what we want. We know what we need. If I want to provide feedback about XCode I have to poke around the Apple site for ages, fill in forms, and finally ask myself whether it is a bug, an enhancement request or ‘none of the above’ that I want to file.

XCode users are worth money to Apple. Let us help you improve our IDE.

2. Creating and deleting files is slow and error prone

The file creation wizard should guess which folder we want to put a file in using the folder files in the same group are located in. I don’t know how the default location to create a file is determined, I just know it doesn’t do that. So I regularly find misplaced files.

XCode regularly bails out when trying to delete files; typically this happens because it gets confused about what to delete when the file is under version control. Please improve. Additionally, it is rare that somebody wants to delete an *.h file or *.m file without deleting the counterpart. No assistance provided. Please improve.

3. There is no way (I know of) that a ‘folder reference’ can work with source files

… and if there is one, discovering it should be a breeze.

Massive bummer. You can’t create an XCode project integrating a third party library without updating the list of source files yourself. Whenever the guys who make the library add or remove a file, you have to update the project manually.

The last time I tried using the ‘blue folders’ (the ones that track content automatically) to include source files, the sources were simply ignored by the compiler.

4. Auto-completion doesn’t recognize the header path

Objective C encourages verbose, literate function names. Auto-completion is important to XCode users. Given problem (3), adding the library headers to a project only works when the library is ultra-stable. Otherwise we end up having to re-add the headers on a regular basis.

Whenever adding a static library, XCode should help us locate public headers and sort these annoyances for us.

5. Typing is slow. Indexing is slow. Opening a project is slow

I love my mac; not the next mac. My mac. There’s no reason on blooming ancient earth that a dual-core computer couldn’t handle a weeny bunch of strings and let us input code at the speed of type. My mac is 24 months old, looks brand new and does everything well except running XCode 4.0.2.

6. Provide an option to hide definition/declaration files from the project navigator.

A tri-state button would sit nicely at the bottom of the project navigator along with custom and time based filters. The custom filter can sort of do it but it’s too awkward for such use – if anything it’s expanding the whole workspace recursively.

On this note, the ‘related files’ button in the code window is a poor substitute for the XCode 3 counterparts toggle. It’s cartesian. It’s complex. It’s 2 clicks versus 1. It’s a gimmick overriding a much needed shortcut.

Nor is the ‘assistant view’ quite solving the problem either.

The assistant view is this wacky widget that puts your .h file on the right, puts it on the left, then locks over something ‘altogether different’ that we inadvertently requested. It’s nice to have but for now it is convoluted and forever after it’s dependent on having a lot of screen space.

7. Adding a group causes the project navigator viewport to reset

This is a bug. It’s annoying and distracting. Please fix it.

This is a flag you can pass along with ‘other linker flags’ in XCode build settings. It tells the linker that your project requires the C++ standard library.

If your project contains *.mm files this is set automatically (implicitly, rather). But what if you wrapped a C++ library using Objective C++ and carefully make sure that no C++ leaks into client code. Now you have a static library wrappedcpp.lib (speaks C++, OC++) and your app tries to link against this but doesn’t contain even one *.mm file?

What then? A bunch of ridiculously obscure linkage errors.

Thanks to Rob Napier, I can go back to my debugging (check the QA on stack overflow)

I haven’t worried about device orientation in a while. Supporting a variety of orientations is *nice*.

On iPad, supporting all orientations is strongly recommended; not supporting ‘upside down’ variants of your orientation is rarely tolerated(*). Unless you have a good reason not to (e.g. accelerometer freak app).

So I thought I’d rehearse a little. I learned new things and discovered an iOS 4.0 cherry that helps avoiding orientation caveats: UIWindow’s rootViewController property.

(*) Keep safe from harm.

How to support device orientation changes?

  • Edit the info.plist file for your target
  • Your views should be managed by view controllers. You can do without view controllers but then you’re pretty much on your own although at least there’s a system callback to tell you the orientation changed (seriously, you can find it yourself).
  • Your view controllers should override shouldAutorotateToInterfaceOrientation.
  • Your nib files should be nicely configured so your widgets won’t fly around in a happy mess when rotated.
  • Know more about how views are managed, and how view controllers relate to the key window (see caveats)

info.plist

Specify supported orientations in the info.plist for your target:

  1. Select your project in the navigator
  2. Select your target
  3. Press/Depress orientation toggles in the summary tab (big icons showing rotated devices).

view controller

Override this and return YES to your supported orientations:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

interfaceOrientation may take one of the following values:

UIDeviceOrientationLandscapeLeft, UIDeviceOrientationLandscapeRight, UIDeviceOrientationPortrait,

UIDeviceOrientationPortraitUpsideDown

Sadly this appears to have a life of its own. Setting the info.plist property doesn’t further restrict a view controller’s response to orientation changes. In other words your plist may say that you only support landscape left/right. If a VC returns yes to all orientations, this won’t prevent its views from rotating.

Configure your nib files

A savvy approach to managing rotation is to create documents that look good both in portrait and landscape mode. It is possible to use different nib files for different orientations (not covering this here).

  • In the attributes inspector for your document’s main view, set ‘Autoresize subviews’ to true.
  • In the size inspector, use the autosizing toggles to determine what should happen to each element when the view rotates. You (or your UI designer) should do this for each element in the UI, deciding whether that element should size to fit / use a fixed size, and how to anchor the element (left, right, top-left, bottom, …).
  • You can toggle the current ’simulated’ orientation of a view using the orientation setting in the attributes inspector.

You can remove/resize elements programmatically (check Apple docs as referred below).

Caveats

In a worse case scenario, changing device orientation will do little other than moving the status bar (if there is one). Two possibilities:

  1. Your view controller isn’t notified of the change, so it can’t rotate its view.
  2. Your view isn’t managed by a view controller.

Read about custom view controllers (link to SDK docs). Under “Presenting a view controller’s view”:

” [...] use only the suggested techniques for displaying the views of your view controllers. In order to present and manage views properly, the system makes a note of each view (and its associated view controller) that you display directly or indirectly. [...] When the device orientation changes, a window uses this information to [notify] the frontmost view controller. If you incorporate a view [...] by other means (by adding it as a subview to some other view perhaps), the system assumes you want to manage the view yourself [...]“

And this, under “Understanding the rotation process”:

“[...] the window object does much of the work associated with changing the current orientation. [...] Specifically, it works with the view controller whose root view was most recently added to, or presented in, the window.”

Only one view controller will receive the event, and propagate it to it’s (unique) view (and the underlying hierarchy).

Note: if you search for UIVviewController in XCode docs, also read the lovely article: “Why won’t my UIViewController rotate with the device”.

Common Solutions

In my experience, using several view controllers and adding their views to the main window is error prone. Pity, because it feels like a natural, no-nonsense approach to displaying views (but see the nice solution, below).

  • Use a unique view controller. Doesn’t sound great but if you have a simple app, at least it’s safe.
  • Display the view controller’s view modally. This often makes sense since a view controller is meant to manage one screen’s worth of content. IMHO the downside is that system semantics are associated with modal transitions, and misinterpreting how these transitions should be used may hurt you. For example, you may be struck by lightning.
  • Use a navigation controller, a tab bar interface or a popover.
  • Hacking a controller’s view down the hierarchy of the controller that receives orientation events. Ugly. However, note that hiding and showing views is a lot faster than adding and removing views. On older devices this may affect the user experience.

A nice solution

I wasn’t desperately happy with *any* of the above. Following the ‘one controller manages one screen’s worth of content’ idea, it would make sense if…

  • APIs prevented us from adding several views to the main window.
  • Any view added to the main window must be managed by a view controller.
  • We could actually tell the window which controller it should be working with.

In IOS4.0 and later, there is a public, documented property that works with UIWindow. You can assign a window’s rootViewController property. This does a lot of work underhand:

  • Remove the existing view hierarchy displayed by the window
  • Add the new root controller’s view hierarchy to the window
  • Make the VC ‘frontmost’. That VC will now receive notifications when the orientation changes.

I tried this and it works like a charm. I seemed less lucky when combining [window addSubview:] with the root view controller property, but maybe it can still work.

Resizing OpenGL surfaces

EAGLView is a utility class for displaying OpenGL content. You can find it in iOS SDK samples and it is often used as a starting point for OpenGL applications.

When an instance of EAGLView is rotated, it calls its [layoutSubviews] method. If you created your EAGLView programmatically, remember to set the autoresizing mask, as follows:

view.autoresizingMask=UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;

Otherwise your EAGLView won’t resize, and [layoutSubviews] is never called.

layoutSubviews calls this onto another utility class, aka ‘renderer’ (typically, ES1/ES2Renderer).

[renderer resizeFromLayer: (CAEAGLLayer*) self.layer];

The sample code provided in ES1/ES2Renderer resizes the underlying buffers correctly, so you could use it as a starting point. I get wimpy when it comes to buffers, but I still managed to get it right using the following ideas:

  • The color buffer is resized from the CAEAGLLayer.
  • We then retrieve the backing width/height from that same buffer.
  • Other buffers (depth, MSAA etc…) can be reallocated using whatever method we already know (remember to use the updated width/height).

Now that we’re a little more familiar with targets. How about we actually stopped being lazy and created a shared library?

How to do it

  1. Select File > New > Target (can also click on the project to open the target list and select the (+) symbol at the bottom left)
  2. Pick ‘Framework & Library’ in iOS templates.
  3. Select ‘Cocoa Touch Static Library’

I have a few files that I find useful whatever project I’m working on; for now I have just removed these files from all my existing targets, and added them to my newly created ‘utilities’ library target. This builds without issues.

Next, I opened the Build Phases tab for a target that should use the library. I drag and drop the library in the ‘Link Binary With Libraries’ section. Ordering is sensitive, so I add my library at the bottom of the list, after the frameworks.

Remember that the library should be listed by every target that uses the library. If your main target depends on a test target, and somehow your test code implies using the library as well, then both the main target and the test target should link against the library.

OK, how do I include the headers in my project?

  1. Click on your project (the project that you want to use your library with) to open the build related stuff.
  2. Select the project. It’s especially useful to include headers at project level if you have tests or use several targets.
  3. search for ‘User Header Search Paths’.
  4. Add the path to the library source file. It’s better to add a relative path. So if your project is under foo/myProj.xcodeproj and the library headers are under foo/myLib/myLib, then typically the path would be ../myLib/myLib
  5. You may need to set the matching target settings (the user header search path in each target) to $(inherited). This explicitly tells a target to inherit the setting from project level.

I feel there should be a cleaner way to do it, but I’ve seen it done by other devs, works for me.

Why do it?

Maybe you have qualified reasons for using a static library instead of sharing files across targets. Or maybe you just want to create a library that other developers can use.

However, even if we’re working on small projects and the ‘dev team’ is just one guy, the bottom line is that static libraries are the better way as soon as you want to share code between your apps.

Even if you define your apps using several products in the same project (a lightweight, moderately evil technique I describe in my previous post), that changes little to the fact that editing target associations in xcode is a manual process that requires patience. So rather than having to add every other code file to a new target whenever we start a new project (or removing undesirable files from a cloned target), we just add our files to the library, and link the library against our project, once and for all.

What cannot be included in a static library?

Pictures, text files, nib files and other non code files cannot be included in a library target. Code and header files can be included. It is interesting that Test and Library targets both allow *.h files, whereas product targets do not.

Can I get my static library to build automatically whenever I rebuild my product target?

Yes; it works the same as target dependencies for test targets.

Under ‘build phases’, drag the library target into the ‘target dependencies’ list. Ben Artin explained very nicely (here) that ‘dependencies are orthogonal to linking, if you want both, you need to specify both’

Reading further

You may find this article useful (from “The Carbon Emitter”).

What if we just wanted to share a little bit of code?
What if we where extremely lazy and didn’t want to learn about XCode 4 workspaces?
What if we didn’t want to create and maintain static libraries?

What if we wanted a solution that’s not even scalable, but does the trick while we bide our time?

And finally, what if we had a bunch of similar products based on a budding ‘framework’. Then we might decide to be evil, and dump all of our products in the same XCode project. Yay.

I decided to have a try. Until I hire another programmer, every day of my life is a Sunday. I found that cloning targets is easy, and just a little fiddling will take us from cloning targets to cloning apps and mutating them into something new.

Creating new targets isn’t hard, but then we have all these files we want to add to the new target. That should be easy as pie, but it’s not.

You can try this on a Saturday too, unless you’re working overtime.

1. Duplicating targets

(right click on an existing target, select ‘duplicate’ and follow the signposts).

If two products (an existing one and a new one we’re about to make) are rather similar, duplicating targets may be the fastest way to setup the new product. It doesn’t duplicate any code or resource. Initially both targets use exactly the same stuff. To ‘fork’ a new product, we then duplicate the resources that ‘aren’t the same’.

The big advantage of this approach is that all existing resources are added to the target right away. So this approach is easy if somebody bothers defining a ‘product template’ that contain little / no product specific stuff.

But first and foremost…

We don’t want the same info.plist, right?

Correct. If we use the same info.plist, we can still have two different products on the desktop, but we won’t have different products in-store. A lot of the meta-data distinguishing a ‘product’ (something users can eventually download) from another is the metadata in the plist.

The fastest way I found to actually clone the plist file is to do it from the desktop (sigh) and adjust the Info.plist File setting in Build settings.

Why my ‘target names’ don’t update in the build selection drop-down? Why do I still see an entry there after deleting a target?

At this point I had created, deleted and renamed several targets. My ‘build selection drop-down’ ignored whatever name change or deletion I carried out.

After a few minutes of deep anxiety, I realized that the build thingy doesn’t directly relate to targets. At the bottom of the drop-down thing XCode 4 shows 3 options: Edit Scheme, Add Scheme, Manage Schemes.

  • After deleting targets, delete the associated schemes (go to ‘manage schemes’).
  • After renaming targets, delete all schemes (go to ‘manage schemes’) then press the top right button (’auto create schemes now’).

2. Setting up a new target

Setting up a new target and adding resources to it is the slower, meaner way to (loosely speaking) ‘clone an existing product’:

  1. Go to File > New > New Target.
  2. Choose Window-based application (or whatever you please)
  3. Select a product name and fill in the company id.
  4. Leave ‘include Unit Tests’ checked (no need to be THAT evil)
  5. Press finish.

The sad point here is that no existing files are included in the new target (other than the boiler plate generated by the wizard) and XCode 4 doesn’t provide much of a nice, quick and easy way to add all these files we want to share across targets. We can select several files at once and edit their target setting in the file inspector, but we can only do this for files that belong to the same group.

3. to share or not to share…

There are several types of resources we might want to share across products:

  • Code
  • Frameworks
  • XIB files
  • Data files
  • Image files

If you use the ‘target clone’ method, at some point you definitely want to introduce these classes that make your app what it is (a new app! with some resources and code borrowed from the old one). Then comes the ‘forking’ question:

  • Do the targets use the same MainWindow.xib?
  • Do they use the same app delegate

If the two targets use a different xib as entry point, it’s easy to fork (because the xib is listed in the info.plist, and surely the info.plist is forked).

Otherwise, the quick and dirty way is to use homonyms. So we may have two ‘MyAppDelegate’ classes (same name, different folder); and we associate one with each target. IMHO this is really evil, but it’s like chocolate. A tiny bit won’t hurt.

You could also check PrEV’s Demystifying app startup article. Knowing more about app startup can help us resolve certain questions pedantically.

I also found a post about renaming projects. I kinda managed it before, but maybe the post is useful.

Conclusion

Maintaining several apps in the same XCode project is possible. It doesn’t mean it’s a good idea. Learning how to do it is a moderately fun way to learn about targets in XCode.

Are we finally migrating to XCode 4?

Laggards start with an edge when it comes to migrating to new/updated solutions: most of the problem areas have already been identified, discussed and resolved. Oh really?

Bread and butter: where’s our stuff?

Apple kindly provides an XCode 4 Transition guide. I’ve only skimmed through it and find myself moderately able to build my existing project.

  • Where is Get Info? It’s kind of been moved to a side panel which is disabled by default. Go to View > Utilities > File Inspector.
  • I added my file, it’s there! But when I build the file is missing. I had several flavors of this error:
    • I moved my .pch file; frankly this has nothing to do with xcode4. The location of the .pch seems to be relative to the project folder by default. so if your .pch is in a subfolder then the path should be changed to subfolder/myPrefix.pch or such.
    • I add files and they get marked red!
    • My files are still not found. Check what the path is relative to (open the ‘File Inspector’). I was migrating files and I noticed that they got marked as ‘relative to group’, and this caused files not to be found by the compiler. Heck, this is rather confusing.
  • Where is the ‘build’ button? I love running ‘just a build’ (instead of ‘build and run’), just to make sure my tests are doing OK. Apparently the toolbar can’t be customized anymore. Sigh… So yea, I got no f****g idea where this stuff is gone.
    => however you can build from the Product menu (Product > Build) or learn the shortcut (Cmd+B).
  • Where is the organizer?
    => Top right button in XCode window.
  • Where is repository/source control management?
    => in the organizer
  • How do I rename my project? It can be done in two ways (see below). Both methods will pop an interface where you can select matching entries to rename in project data. It is crude, but works. Unfortunately this doesn’t rename folders created by the project wizard. So MyProject/MyProject would be renamed to YourProject/MyProject (to keep tidy, it may be a good idea to rename your source and test folders to just ’source’ and ‘test’ right after creating a new project)
    • In the project browser (click-wait-click onto the project icon/name), in the same way as you would rename a file in Finder.
    • In the attributes inspector (top right, edit project name) when the project node is selected.
  • How do I set NSZombieEnabled? Go to the scheme manager and edit environment variables for the matching target. If you can’t find it check this nice post from 42games (pics included).

    For a quick, yet more comprehensive tour of where the f***k’s everything in xc4, read pilky.me.

    Interface builder…

    IB is now integrated within XCode. It’s a bit weird, and also means that we can’t take advantage of a second display to work with IB and XCode simultaneously.

    • The attributes inspector can be opened using view > utilities > attributes inspector. It’s easy to toggle between inspectors (somehow renamed ‘utilities’) (file inspector, attribute inspectors etc…).
    • Likewise outlets etc… are also in the utilities panel.
    • The document window/nib browser has been replaced by a kind of left hand toolbar when opening a nib file. By default this toolbar would show something like unlabeled icons for the file owner, first responder and main view. There’s a tiny triangle at the bottom left that will reveal a hierarchic view that looks like the old nib browser.

    Workspaces

    • Create a new workspace: go to File > New > New Workspace. Easy.
    • Add a project to your workspace: drag the project file in your workspace/project browser. Drop towards the far left of the project browser (otherwise it will drop inside an existing project).

    Workspaces don’t do away with having to setup static libraries as a better way to share code across projects; however workspaces ‘look like they might be nice’. If you’re experience code sharing issues, workspaces may be the best reason to upgrade (to XCode 4, that is).

    What can’t I close the ‘extra tabbed editor’?

    Go to View > Editor and select Standard.

    The good, the bad, the ugly (and ((self=[super init])))

    This has always been OK; better than OK in fact, it’s an OC idiom:

    if( self=[super init] ){ … }

    Now it’s not. It triggers a warning. Well…

    • if(self=[super init]) is sucky. Instead of having well formed constructors we have this magic incantation that doesn’t even make it rain.
    • if((self=[super init])) is suckier. It’s ugly.

    So I did the suckiest thing. I switched my compiler version to LLVM GCC 4.2(*), which appears to be my so called ’system default’, and unchecked the missing braces and parentheses warnings. I’m sure you think it’s a bad idea to disable warnings. So I went back to XCode 3.2 momentarily, to find that the warning’s always been unchecked. WTF, there’s more than 100k iOS devs out there, and here we are, wondering why our projects are forcibly ‘upgraded’ the betterest-most-pedantically-improved-style.

    (*) I just did it. You can find equivalent solutions whatever compiler version you set.

    What do I do with this ‘Missing File’ *.xcscheme is missing from working copy warning?

    It appears that when deleting/renaming schemes, the schemes may not be mark-deleted from source control. However XCode keeps track of our working copy, so it will soon be complaining that the file is missing from the working copy.

    Use your favorite source control utility to remove the file from the repo; the warning will disappear.

    Itunes’s messed up

    • upgrading iTunes didn’t work for me.
    • I reinstalled iTunes as described in this post on callingallgeeks.org. This cleared up the errors that were appearing in iTunes.

    C++ Migration Quirks

    I had hardly managed to download and install this little mammoth of an IDE when a colleague turned up, trying to migrate existing C++ projects to XCode4. Here are the main issues we encountered:

    MainWindow.xib not found. The project we looked at didn’t actually used a nib file or a main window (not very surprising with a migrated-from-C/C++-game-type-y-project). It somehow hooked a custom ‘main controller’ object using UIApplicationMain(…). However, the main window was listed in the project’s info.plist.

    Note that this error is commonly seen, even with projects that actually use a MainWindow.xib; if XCode 4 doesn’t see your nib/xibs anymore, check the simple solution suggested on the NSLog(); blog.

    => We deleted the MainWindow entry in the plist file (not just removed the name, actually removed the entry). If you list a MainWindow in your plist file, but actually start the app in a different way, XCode 3.x will just ignore the main window (most likely, fail silently). XCode 4.x will ‘fail fast’ (in other words, crash your app).

    “Bad codegen, pointer diff linker error…”. This is a linkage conflict that will typically happen when linking against several libraries built within the same project. The somehow likely reason this happens is XCode4 changed it’s default policy for handling external library symbols that do not declare access restrictions. So before these symbols didn’t get exported, but now they do, and the same, intended-to-be-internal-by-default-symbol is duplicated across two libraries or more.

    =>  Edit build settings for each target (the libraries we’re building and linking against): change the ‘Symbols Hidden By Default’ setting to true (as suggested in this stack overflow item). Now that I’m looking at one of my existing projects in XCode 3.x, I seem to find that ‘Symbols hidden by default’ is already checked).

    Linkage error (files not found)

    By default, XCode 4.x does not use the same build output directories as XCode3.x. Here we just updated (erased) absolute paths we found under ‘path to search for libraries’ or such.


    After a short break in Paris, I’m finding my game physics module where I left it: unfinished. I’m afraid this post isn’t all too informative, but I’ve renewed my commitment to keeping this blog a developer’s diary…

    PhysicalModel, for all it’s worth…

    I tried to have a look at how PhysicalModel could be implemented. The idea behind PhysicalModel was to have a protocol giving access to physical bodies and/or colliders. This uses a well known pattern: instead of adding the items we want to process to a list or set, we have a protocol specifying how the items are being accessed (a kind of iterator). But frankly I doubt whether the pattern is relevant here. For the sake of efficiency we’d probably allocate an old style array of pointers and iterate that instead, because it’s much faster. For the sake of simplicity, we’d just use an NSArray.

    What partakes the physical model?

    How do I initialize and maintain the content of PhysicalModel? Nothing explicitly specifies the content of PhysicalModel. We have candidates, but none of these actually describes the model the way I want it to be:

    • I have the cast (the list of actors). To keep things simple i’d like every actor to be modeled as a cylinder.
    • Then we have the terrain. I’d like every platform to be modeled as a special physical body with detailed processing (on a per face basis)
    • Finally, there are a number of elements present in the scenegraph that I would model as obstacles. For these, cylinder/spherical bounds may be enough.

    Provisionally, I decided to rebuild the model at the beginning of each chapter. The physical model might need additional maintenance – for example, if actors are added/removed while playing a chapter – but it seems like a decent start. I have a utility class in charge of (re)building the model, looking like this:

    @class AntistarCast,WalkableScene,PhysicalModel;

    @interface AntistarPhysicalSystemBuilder : NSObject {

    }

    +(void)buildUsingCast:(AntistarCast*)cast

    terrain:(WalkableScene*)terrain

    target:(PhysicalModel*)model;

    @end

    All we have to do to build the model is iterate the terrain/cast and generate physical bodies for matching elements.

    Simplifying the model

    I had Collider (something other objects can collide with) and PhysicalTarget (can be affected by collisions) protocols. I got rid of that and only kept PhysicalBody. As a result, processing is simplified – each PhysicalBody instance is tested against all other instances for overlaps.

    Whether we use separate interfaces or not, we can still reduce overheads - only moving objects need to be tested for collisions. So maybe the distinction between colliders and targets isn’t very useful at this point.

    I postponed writing this article for a while. One or two months ago I wrote a few words on this topic, but that was really more about actuators and less about activities.

    An activity is a kind of ‘controller’. I’m not very happy with this terminology. In MVC parlance, controllers have privileges (access to view and model). Activities may or may not have such privileges (I try to write activities that can run without a view, makes testing a lot easier). An activity is an object that manages the behavior of a game object over time. Examples of activities may include walking, fighting, performing an action and the like. Typically an activity achieves their goal using delegate activities or actuators. For example, at the moment I have a ‘Fighting’ activity. This activity processes a list of targets (opponents) over time. Whenever the agent is available, Fighting instantiates a delegate activity (ReachAndPerform), causing the agent to hit the nearest target.

    Base class for activities (Activity.h)

    @class FrameCallDispatcher;

    @interface Activity : NSObject {

    FrameCallDispatcher* dispatcher;

    }

    /** start this activity */

    -(void)start:(FrameCallDispatcher*)_dispatcher;

    /** Complete as soon as possible. Resources should be restored to ‘idle state’ */

    -(void)stop;

    /** Pause immediately */

    -(void)pause;

    /** Resume execution after pausing or stopping */

    -(void)resume;

    /** stop immediately */

    -(void)interrupt;

    @end

    As you can see the design of this class is concise. The so called FrameCallDispatcher is a custom class passed to the start method. Most activities do not use this directly, instead FrameCallDispatcher is typically passed to an actuator that then registers to it to receive frame events (e.g. to update the location of an object at every frame).

    So far, I have found the following to hold true:

    • Writing, testing and debugging activities is time consuming. Implementing game behavior without activity classes, however, is much worse.
    • Over-designing the base class for activities causes bugs. Preempting the details of how an activity interfaces with it’s delegate, or other actors in the system, seems to be a bad idea. For example I haven’t resolved to have an ‘addActivityListener’ method at this level, or an ActivityListener interface. This is because activities complete (or fail) in rather idiosyncratic ways. This is pretty similar to the way GUI components work. Following the parallel, needless to say there are events with a kind of generic flavor and I could allow generic observers on this basis, but so far I have little use for that.
    • Activities are useful to implement game logic. Activities are generally undesirable when specifying game logic. This is mainly because code that instantiates and starts an activity looks less intuitive and less object oriented than code that invokes a method on an agent, viz…

    [dog attack:cat]

    is clearer and more concise than:

    AttackActivity* attack=[[AttackActivity alloc]initWithAgent:dog target:cat];
    [attack start:frameCallDispatcher];

    Methods all activities should implement

    Start

    This causes an activity to start. This typically involves the following steps:

    1. Ensure that all resources are still available. This is important if the activity has been instantiated earlier since some of the resources needed to instantiate this activity may no longer be available.
    2. If the activity is an actuator, it should register to the frame call dispatcher. If the activity uses one or several delegates, these delegates should be instantiated and started.

    Stop

    Stop causes an activity to stop executing, and restores resources to idle state. For example we could have a Walking activity. Calling stop will cause the actor to stop walking and go back to their ‘idle’ animation. Being fairly high level, stop needn’t action resources immediately, and sometimes it may be undesirable for stop to do anything at all.

    Pause

    Causes an activity to pause. calling pause on the Walking activity will cause the actor to stop in mid-air.

    Interrupt

    Causes an activity to stop immediately, interrupt it’s delegates and release it’s resources.

    Resume

    Can be called after stop or pause and does just what it says. Conflating resume and unpause may not be a good idea, but feels intuitive.

    A word about the design of activities

    I won’t get into the details of how activities can/should be designed today. If the behavior of agents is extremely simple, you may not need activities after all. However, things quickly get to the point where all kind of puny book-keeping (or seriously involved processing) is required. Then activities become useful as a way to encapsulate the details of what’s going on, rather than having (really) huge agent classes.

    Activities can also be used to coordinate the behavior of several agents simultaneously. This immediately brings another problem: activities don’t always own the resources they manipulate. For example, take a ‘Picking’ activity. This causes an agent to go fetch an item on the terrain. So we pass the agent and item to the Picking constructor. But until this activity has completed, anything can happen to this item – it may disappear (e.g. power up left behind by a monster) or another player/NPC may have collected them already, etc… Game behavior happens over time. As a result, high level concurrency issues easily occur when dealing with game behavior, and activities are typically in charge of dealing with this stuff.

    Finally, it is savvy to reuse activities rather than deallocating them. This reduces memory allocation/deallocation and can become necessary. Unfortunately, it is fairly easy to introduce bugs while trying to optimize memory management in this way.

    Why is Activity not a protocol?

    It could be. I’ve implemented Activity as an abstract class because I find it convenient. For example, here is the implementation for stop:

    -(void)stop{

    NSAssert(NO,@”!implement”); //[self doesNotRecognizeSelector:_cmd];

    }

    [self doesNotRecognizeSelector:_cmd] ensures that invoking the base method will cause an exception to be raised. I’m including this because it is a popular approach to faking abstract methods in Objective-C. I prefer using an assert.

    Using a protocol may be wiser. Would make this stuff compile safe, right?