Skip to content

Archive

Tag: Objective-C

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.

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)

Back to the happy days when I started enjoying my own, home-made dev tool (Antegram for Java), I stopped using a doclet generator. I could bring up any API I’d created without hiding whatever I was currently working on. XCode simply isn’t designed to allow you to do that; Eclipse, for all the bells and whistles, isn’t much better.

In summary, for all I care auto-generated documentation is often little more than a way to browse APIs quickly when auto-completion doesn’t do the trick. I might end up writing a little utility to rip headers and signatures and put together something that fits that purpose better than a professional doc tool. In the meantime, I had a quick check on what we can already use.

I came across Doxygen – not for the first time. Even Apple seems to recommend it (check this link) and there is an in-depth tutorial at Duck Rowing

Two unpretentious doc generators you might want to check are nudoc and appledoc. Appledoc seems to be actively developed (v2.0 out January 2011)

“How many games feature a handsome British spy jumping from a speed-boat to a helicopter? “

This post is exposing a little exercise involving information hiding. It is a little geeky and non-commital, but you might enjoy it. I start with a flat data structure – my 3D data is something like ‘just a set of nodes with location and orientation information’. I have a lot of code relying on absolute coordinates and the set structure. Then I somehow manage to introduce a translation hierarchy, by subclassing my Vector class and changing no more than 20 lines of code everywhere else.

This worked out because I use Objective-C properties to wrap vector coordinates. Interestingly, I’ve been tempted to replace my vector class by a struct for ages, because just retrieving coordinates generates performance overheads thanks to dynamic binding. Well, not today…

Please. Try this at home. We need more clean code and less witchcraft during office hours :)

OK, a few months ago, I dismissed scene graphs with a shrug. Now I’ve got these moving platforms in my game. Not quite the glamor of your fav. cross-motorized pursuit?

Unfortunately whatever keeps my actors’ feet on the ground wasn’t designed with moving platforms in mind. Seems like a little bit of a hierarchy has a case.

Let’s see how I can unflatten the game graph.

  1. All my nodes have a location vector.
  2. All my actors and props have a terrain field indicating what they’re currently working on.
  3. Nowhere that reads a location vector needs to know about a child’s position relative to its parent.
  4. Nothing should set a node’s location directly, now knowing it’s meant to be relative to the node’s parent.
  5. Reparenting nodes can’t just be ‘done like this’. The location needs to update.
  6. Getting a node’s location is about to become potentially time consuming.

Given (3) I could just substitute the synthetic accessor (write a function that silently substitute the relative location to an absolute one). However, given (6), I should no longer return the location vector. I should define a getLocation:(Vector*)placeHolder method to encourage callers to retrieve the location only once.

Given (4) I can absolutely not substitute the current accessor. Or rather… that would imply backing a vector subclass with the capacity to propagate changes back to the relative location. Hey, that looks interesting:

-(Vector*)location

now returns a relative vector, so that if we do:

location.x=10;

Instead of setting the x component to 10, it adds the difference x1-x0 to the x component, where…

x0 is the current, absolute location.
x1 is (in this example), 10.

Finally, given (5) and (2), I need to change the terrain field to parent and substitute the accessor for ‘parent’ with ‘reparenting code’.

Getting dirty

In my Element class ((non-)scene-graph node):

  • I remove terrain from @synthesize. I will write my own accessors for terrain (for now, It’s OK not to have explicitly named ‘parents’)
  • The getter is unchanged.
  • The setter includes reparenting code.

-(void)setTerrain:(Terrain*)t{

location.parent=t.location;

terrain=t;

}

Trivial. However, let’s examine the implementation of location.parent = … in RelativeVector (after-note: this implementation is so very bad).

-(void)setParent:(Vector*)p{

float x=self.x;

float y=self.x;

float z=self.x;

parent=p;

self.x=x;

self.y=y;

self.z=z;

}

This looks equally impotent, right? What does this do then?

  1. save the absolute coordinates of the relative vector.
  2. Reassign the parent. At this point, our relative vector has changed its absolute location
  3. Move the vector back to it’s absolute location. That’s because self.x, self.y, self.z hide a setter like.

-(void)setX:(float)x1{

x+=x1-self.x;

}

I’m not done yet. Every element needs to use a RelativeVector as location.

My first attempt at compiling this stuff generated a whooping 123 errors. That’s because I made my ‘vector’ property (aside from the actual field) a RelativeVector, and classes that use Element don’t know what a RelativeVector is. Just retyping the property to Vector, quite logically, works out.

A Beautiful Feeling: The Sense of Impending Disaster

Gotta run this. Confidence level: 12.5%

  • The first run is stuck in an infinite loop. I wrote code that could do something like it earlier in the afternoon. Surely I can remove this code (for now).
  • The second run brings up my avatar on a black screen. No terrain. If you haven’t already noticed that RelativeVector setParent: assigns all absolute coordinates to absolute x, scroll up.
  • The third run is more entertaining. The avatar is still on a black screen, but I can walk it around and ‘feel’ the terrain. I know this terrain quite well, there’s no mistaking it for anything else. Then I got suspicious because I haven’t tested stage zero since yesterday. So I fire up stage 1 instead and… everything looks OK. Whatever happened to stage 0 can be investigated later.

Now, if I get my avatar to walk from terrain to terrain, I can ‘jump into nowhere’. Not part of the plan. That’s easy to track. Just put in a breakpoint in the reparenting method. Good opportunity to realize that the setters in RelativeVector aren’t quite right. I correct my setX/Y/Z to look like:

-(void)setX:(float)x1{

x=x1-parent.x;

}

By the way, just to confirm – if a class defines an accessor for z, then, from within the class:

  • self.z => invoke/return the accessor
  • [self z] => invoke/return the accessor.
  • z => refers to the field, defined in this, or a superclass.

Good, but my avatar can still teleport into a vast emptiness of cosmic delusions. That happens also when walking towards the edge of a terrain. Better, I can teleport from the edge of a terrain to a far away terrain. Nice feature for a game… if anybody can figure how to use it.

I forgot to remind myself that there are many ways to manipulate a Vector instance. All methods that do that need to be updated as well. Otherwise strange things are bound to occur.

No more teleporting then… A little test with my moving platforms also shows that all related bugs have disappeared:

  • actors used to sink their feet into the ground when the platform moved up
  • actors used to hang in mid-air if trying to walk off a platform.

I haven’t removed the old code that tried to project actors back onto their current platform. This is fairly expensive to run, so I should really get rid of it.

It may come as a surprise that ‘just moving actors back to ground level’ generated bugs. The best way to understand is to try writing similar code. ‘keep feet on the ground’ without anything like physics, but handling stacked platforms, nearby walls and/or dirty geometry, can space out a little.

Conclusion

  • Introducing a hierarchy seemed like a good move. Not having one at this stage caused several bugs. The most important bugs are fixed, and a couple of other bugs got fixed accidentally as well.
  • The little surgery I’ve done is very localized. It could be swapped for something way more explicit. Instead of spending two or three hours trying to be smart, I could have replaced a lot of code. That would likely take the same amount of time (I actually believe that might have been a better choice).
  • Structurally, this feels like an improvement. Not a full blown scene-graph complete with transform chains yet, but going towards it.
  • I’ve gone quite far without a scene-graph. My conclusion is that a lot of 3D code likes manipulating absolute coordinates. The right way to create a scene-graph based engine is probably still to… …design it this way, from day one.
  • I dismissed question (6) altogether. I’d rather fix my bugs first, then optimize next if there is a need.

Unlike Java and C++, Objective-C also allows you to augment the behavior of a class even if you don’t have the source code for that class. You can redefine methods in this way, but you can’t invoke super or define new instance variables(1).
This is done by redeclaring and redefining the class and associating the new declaration to a so-called category.

@interface NotMyClass (MyCategory)
@class NotMyClass (MyCategory)

A very common use of categories is declaring private members. Objective C doesn’t really seem to have a qualified option for declaring private functions (and all variables appear to be private, although they’re easy to expose using properties). When we want to hide methods from other classes, we typically add an interface declaration at the top of an implementation file, like this:

@interface Foo (private)
// private methods
@end

@class Foo
// implement everything Foo, including private methods
@end

Your private methods are hidden from users of Foo because a class Bar using Foo imports Foo.h, and all private methods are actually specified within Foo.o; that’s it – ‘private’ as above is just a label for your category and has no magical meaning associated with it.

Other than for declaring private functions, you surely don’t need to use categories and your might actually want to avoid them – yet categories do have uses:

  • Often, different applications need to use the same class in different, maybe conflicting ways.
    >> Many board games could take advantage of a Board class and would like to use the same data structure and basic functionality – however, different board games also require different board functionality.
    Each application can define it’s uses of the class without having to change the original class definition or define a subclass. This has many advantages:

    • Better than ‘loading’ the class with additional methods for each game – Since we don’t change the original definition we don’t overload the class, so we avoid clutter and potential conflicts.
    • Better than subclassing. We don’t need to invent a quixotic name for the subclass.
    • Better than delegating. In many object idioms, delegation is often a good alternative to inheritance. However, delegation fragments object definitions and makes designs (and code) harder to understand.
  • Sometimes, you want to add the same or related functionality to several classes long after you defined the original classes.
    • Keeping related functionality in a designated ‘category file’ can improve the design of your application. In this respect you might read that categories allow ‘scattering’ a class implementation. While that doesn’t sound terribly helpful, categories really allow you to keep together functionality that cuts across classes, and that is helpful.

Categories should be used carefully – especially in a team environment and when functions are overridden – as using categories might actually obfuscate your code.

In my the last article I solved a technical issue related to my action graphs. Now I want to make it easier to write powerful scripts for my actors. Let’s recall a fragment from the previous example:

Actor* dog=[[Actor alloc]initWithX:0 y:0 z:0 tag:@"dog"];
OnApproach* inner=[[OnApproach alloc]initWithSource:dog target:@"actor" range:30.0f];
XAction* chase=[[MoveToActor alloc]initMovingActor:dog to:inner.target];
ReflexMap* reflexes=[[ReflexMap alloc]init];
[reflexes add:chase on:inner];

This isn’t practical, for several reasons:

  • The script requires defining an actual actor. Often, we’d like to specify ‘class behavior’ instead – maybe we want to describe general behaviors associated with dogs.
  • All this [[Actor alloc]init… stuff is about OK for framework level stuff. For behavioral scripts, it is too heavy.

What we’d really want to write is something like (check the previous article for reference)

class Dog{
  - bark at actors within 60 metres
  - chase actors within 30 metres
  - bite actors within 1 metre
}

I don’t want to get into the writing/binding of a scripting language and interpreter, but we can surely clean things up and get it closer to the above.

A Script class

I’ve specified a Script class with convenience methods. With these methods added, the ‘guarding dog’ script now looks like:

Script* s=[[Script alloc]init];
//
[s type:DOG];
	[s let:BITE when:HUMAN within:10];
	[s approach: HUMAN whenWithin:30];
	[s let:BARK when:HUMAN within:60];
[s xType];

type: and xType: tell the script to start/end a class declaration. The other functions are meant to be translated into an action graph. The next step is to decide how this is done. In the meantime, this is worth a couple of comments:

  • We no longer need defining a dog actor. The DOG tag allows us to define class behavior. This doesn’t prevent us from defining ad-hoc behaviors for a given actor (use the tag only once). I hope that tags will prove very useful helpers in writing concise, yet powerful scripts.
  • Script methods are somewhat ad-hoc. However, this is probably OK. I’m trying to simplify 90% of scripting. Having said that, the current script spec still leaves out a lot of the (structural/modal) complexity of the action graph.

Implementing the script class

So far my script class is just semantics. We want to do something with our semantics:

  • We want to store the script in some form.
  • We want to be able to make a script current on a given ‘stage’. In other words, when we attach the script to a scene or virtual worlds, we want our actors to behave according to that script.

The classes provided by my framework so far are not meant to describe a script. They are normally instantiated as runtime nodes in an action graph. At best, I can use them as prototypes, and this is exactly what I tried first. Here is a sample function implementation:

-(void)observe:(tag)kind{
	NearestActor* condition=[[NearestActor alloc]initWithAgent:proto target:kind];
	XAction* response=[[LookAt alloc]initWithAgent:proto lookingAt:cond.target];
	[map add:response on:condition];
}

This can potentially get very untidy. Say we had an actor with a given tag. we’d have to go back and check for all rules including an instance of the same-tag prototype and duplicate the rule so it becomes applicable to that actor. The reason why this process can become messy is that neither conditions nor actions enforce the object paradigm. The Script class, on the other hand, ‘starts with typing’. it assumes an actor as the context of any script statement.

As a result, it is probably wiser to define separate constructs used to store behavior definitions associated with a tagged actor. This is simply because doing ensures we track typing information at least until we actually bind a runtime actor to its behavior. Given an on-stage actor, we can then collect definitions for each of the actor’s tags and generate reflex maps accordingly. At this point, none of the reflex maps will be associated to the actors per se, which may cause other problems. This, however, goes down to a little of book-keeping.

Script structure – draft

I used the following classes to store script nodes:

  • Type - A type is associated with a tag name and (for now), a top level selector.
  • ScriptDef – ScriptDef is the base type for script elements, in this case ‘selector’ and ‘statement’
  • Selector – A selector specifies a ReflexMap (should be explained in my previous article)
  • Statement - For now, my statements are structured, conditional statements. Probably I need to break this down later, but for now this form should cover most of the interactions I wish to describe using the scripts.

Interpreter

I then defined an Interpreter class responsible for setting up a script given a Stage and Transition. This reads the script; for each class, I retrieve the actors bearing the matching tag name and build an action graph based on the class definition. I muddled a little more with my existing Condition and Action subclasses, but somehow managed to tie everything together.

Next time I’ll do some testing to check how everything works, and try to summarize things a little.

Recently, I started designing a game engine with a few simple goals in mind:

  1. My game engine is concerned with managing a virtual world model. It is not an animation engine or a sequence/transition manager.
  2. Although I developed a rough and ready animation API, the model must be separate from that API. This is so that I can later rewrite view using a 3D engine or whatever else.

I’ve been muddling a little bit with behavior programming. After ‘going dark’ for a few days I’ve decided to share my experience as I believe this could illuminate some design points.

Behavior programming – a draft API

A few important classes from the draft API:

  • Condition – a condition is an object that returns a boolean value, so it has a (BOOL)check method.
  • Action – an action is an object with a (void)apply method.
  • ReflexMap – an action mapping a trigger (a Condition) to a response (an Action). When apply is invoked, the reflex map iterates the current action, if any. If no action is currently selected, ReflexMap iterates its list of triggers. The first satisfied trigger condition causes it’s response to become current.

As you can see, the API is based on objectified functions. This is a choice, maybe I’ll get a chance to explain why another time.

An example

Here is sample code used to program simple behavior for a guarding dog:

Actor* dog=[[Actor alloc]initWithX:0 y:0 z:0 tag:@"dog"];
//
Condition* outer=[[OnApproach alloc]initWithSource:dog target:@"human" range:60.0f];
Condition* inner=[[OnApproach alloc]initWithSource:dog target:@"human" range:30.0f];
Condition* close=[[OnApproach alloc]initWithSource:dog target:@"human" range:10.0f];
//
XAction* bark=[[ActorGesture alloc]initWithActor:dog action:BARK];
XAction* bite=[[ActorGesture alloc]initWithActor:dog action:BITE];
XAction* chase=[[MoveTo alloc]initMovingActor:dog to:nil];
//
ReflexMap* reflexes=[[ReflexMap alloc]init];
[reflexes add:bite on:close];
[reflexes add:chase on:inner];
[reflexes add:bark on:outer];

The @”foo” bits just represent strings (in case you’re not too familiar with Objective C). I use those strings as tags, so the @”human” tag allows OnApproach to only target human intruders (not rabbits, leprechauns and so forth…)

As illustrated by this code, although the idea of defining rules using conditions and actions seems OK at first, the design isn’t. The problem is that a Condition (in this case OnApproach) can be fulfilled in various ways. When the condition is fulfilled, we need to pass data to the action to effect it correctly. So in this case onApproach is fulfilled with a given target, but MoveTo cannot bind the target detected by OnApproach. Let’s try to fix this.

Binding precondition output to postcondition input – 1: using arbitrary parameters

My first impression is that the OnApproach condition should be replaced by an event call processed by a listener, so we’d have something like:

on:(Actor*)actor approaches:(Actor*) agent{...}

The downside is that doing this will require that we re-implement the event handling function for every trigger/response pair. We don’t want to write a new class for that every time. We do need to bind the output of the trigger to the input of the matching action. We might then change change the Action and Condition classes:

@interface Condition
-(BOOL)check; // unchanged. we need to return a boolean value anyway.
-(NSArray*)result; // OnApproach will place a reference to the approaching actor in this array.
@end

@interface Action
-(void)apply:(NSArray*)param // allows injecting data into the triggered action.
@end

We still need to tell ReflexMap which parameters to inject into MoveTo. So we change a function in ReflexMap:

add:(Action*)action on:(Condition*)trigger;

Now becomes:

add:(Action*)action with:(int[])params on:(Condition*)trigger;

And our reflexes are then setup as follows:

int[] args={0}; // addresses the only output from OnApproach
[reflexes add:bite with:args on:close];
[reflexes add:chase with:args on:inner];
[reflexes add:bark with:args on:outer];

This solves the problem, but lacks clarity because conditions and actions now return/accept arrays of arbitrary length and content.

Binding precondition output to postcondition input – 2: sharing placeholders

The next idea is as follows: what if we could arrange that whatever target defined by OnApproach is addressable using MoveTo?
To do this requires modifying both OnApproach and MoveTo. On the bright side, we needn’t change the Action and Condition signatures:

  1. I defined an ActorRef class. ActorRef owns an Actor property (I could use a pointer to pointer, but that would be a little confusing).
  2. OnApproach defines targetRef as an ActorRef instance. When a target is detected, targetRef.actor is assigned.
  3. MoveTo also defines a targetRef property. When MoveTo is initialized, we pass the ActorRef instance owned by our OnApproach condition.

We can now change the original example as follows (skipping the bits that didn’t change):

OnApproach* inner=[[OnApproach alloc]initWithSource:dog target:@"actor" range:30.0f];
XAction* chase=[[MoveToActor alloc]initMovingActor:dog to:inner.target];

This seems to solve our problem nicely:

  • Type safety isn’t compromised.
  • The core interfaces remain simple
  • The binding process doesn’t involve ReflexMap
  • The code used to define our test script is simple and readable, compared to solution (1).

OK, enough for today then. Next time I’ll look into a way to further simplify behavioral scripts, as they are still a little heavy.

If you’re trying to write your first iPhone/iTouch applications or are struggling to put together a small to medium size application, this article may help.

This article assumes you have the ‘kind of understand’ feeling about MVC that most programmers get after digging up a little material on the topic.

A Basic Model View Controller (MVC) setup

In xcode, select new project > view based application. The following classes are created for a ‘Z’ project:

ZAppDelegate – Application Facade
ZViewController – Root controller

The only classes missing are a view class and a model class.

Basic view setup:

  • Create a ZView class if you need to customise the view provided by ZViewController.xib programmatically. Assign ZView as class of the root controller’s view from the property inspector in interface builder.
  • If you only want to gain access to UI elements added to the view, do the following:
  • 1 –  open ZViewController.xib and add your UI elements. In this example, I assume a label (UILabel class) was added.
    2 – add an IBOutlet field to ZViewController.h, like this :
    IBOutlet UILabel* myLabel;
    3 – In ZViewController.xib, notice that myLabel now appears in the file’s owner property inspector (click the blue arrow pointing right in prop inspector to view outlets). It has a little keyhole on the right.
    4 – From myLabel‘s keyhole, click-drag a connector to the actual label.

    Step 1 creates the actual UI element. Step 2 allows programmatic access to the created UI element. Finally, Steps 3 and 4 ensure that the field we have created maps to the actual UI element.

Basic Model Setup
Now suppose we created a ZModel class to hold our application data model. We probably want to gain access to the model from the controller. With a model driven view (view is mainly required to reflect model state), it is often convenient to keep a reference to the model from our view as well. This brings two questions:

1 – Where do we create the model? In other words, when should it be initialized?
2 – How do we provide the controller and view a reference to the model

These questions can be answered in various ways. For simple applications, here’s a recipe that works.

  • Instantiate your model class in ZAppDelegate::applicationDidFinishLaunching
  • Still in the same function, assign the model to the controller and view.

ZAppDelegate naturally owns a reference to the controller (viewController) and view (viewController.view). This makes it a convenient placeholder for our data model. Besides, even if we change the controller and/or view while the application is running, we can still access the model root. Finally, applicationDidFinishLaunching clearly holds the code used to add the view to the main window, so we are sure that the view binds the model before getting rendered the first time.

Processing user interaction

If your view is processing touches (touchesBegan etc…) it may be convenient to assign a backward reference from the view to the controller. Again, this setup can be effected from applicationDidFinishLaunching. We can then query the controller to perform high level actions when touches occur.
You can work around potential (compile-time) cyclical dependencies between the view and controller by only referring the controller using an
@class ZViewController
annotation before your interface declaration/class def. Although this may trigger a warning, you don’t need to import ZViewController to invoke methods on it as Objective C resolves method calls at runtime.

That’s it for now…

If your application is becoming complex, you may need to look into more developed MVC solutions – e.g. get inspiration from the PureMVC framework or maybe try my F* Meta-Pattern.

So much for commonsense. What’s the difference between:

NSArray *foo=[NSArray arrayWithObjects:a,b,c];

and

NSArray *bar=[NSArray alloc] initWithObjects:a,b,c];

Should be pretty much the same thing, right?

As it stands, I populated NSArray/NSMutableArray with UIImage pointers. Trying to use any UIImage* from the resulting arrays consistently crashed the iPhone simulator using …arrayWithObjects:… .

From now on I will always use …alloc]initWithObjects:…
instead.

Don’t take my word for it, try this at home :)