4th July 2009

Objective-C Memory Management tip o’ the day

Still getting used to this whole memory management thing. I thought I had it pretty much squared away, but just ran into a spot where I got complacent and let a bunch get by me.

I've been working mostly with cocos2d, where most of the objects are created with a static "node" or "spriteWith..." type methods, which return an autoreleased instance of the class you want.

C:
  1. mySprite = [Sprite spriteWithFile:@"some.png"];
  2. myScene = [SomeScene node];

Since these autoreleased, you need to immediately do something that's going to retain them if you want to keep them around. In most cases, with something like a sprite, you are adding the sprite as a child of another object, which retains the sprite that is added. In some cases, you might be adding it to an array, which also retains it. In these cases, that's usually all you want to do, because then when you remove it from the parent or the array, or release the array or whatever, the instance is released and dealloc'ed.

C:
  1. mySprite = [Sprite spriteWithFile:@"some.png"]; // autorelease
  2. [myScene addChild:mySprite]; // retains mySprite
  3. ... later ...
  4. [myScene removeChild:mySprite]; // releases mySprite. retainCount reaches 0, and it's dealloced

Of course, if you want the sprite to stick around after removing it from the parent, retain it explicitly. Also, if you are NOT immediately adding the autoreleased object to something that will retain it, you will need to explicitly retain it:

C:
  1. mySprite = [[Sprite spriteWithFile:@"some.png"] retain];

Now it will stick around, so you can add it to a parent object later. But remember, when you remove it from the parent, it will still have a retainCount of 1, so when you are really done with it, you'll need to give it one more release:

C:
  1. [mySprite release];

So this brings me to where I messed up. Again, I got really used to these autoreleased objects. But then I created several "regular" objects for my model, using alloc/init, and added these to an array. I was stuck in autorelease mode, so I was doing something like this:

C:
  1. myModelObject = [[ModelObject alloc] init];
  2. [modelArray addObject:myModelObject];

Of course, when you alloc something, it gets a retain count of 1. This is not autoreleased. Adding it to the array, retains it again. Later, I was removing the object from the array, thinking that was the end of that. But it still had a retain count of 1. I wound up with a bunch of model objects never getting dealloced. Worse, these model objects were holding a reference to the view (I know, I know, questionable architecture to say the least), so even after the view (which was a cocos2d sprite) was removed from its parent, it was still being retained by the model and was sticking around, eating up not only memory, but running animations behind the scenes. The solution was simple:

C:
  1. myModelObject = [[ModelObject alloc] init];
  2. [modelArray addObject:myModelObject];
  3. [myModelObject release]

You're safe to release it here, because the array is retaining it.

Now, this wasn't some blinding realization. As soon as I saw the alloc/init without a release, it was a "duh!" moment. Found these in several places, cleaned them up and got a stellar performance boost. (Now I'm going to clean up that model/view connection.)

Anyway, not really sure what the point of this is. Just one of those things where you're happy to find something big that really helps your app and you want to share it with someone. My wife and daughter didn't really care. :)

posted in Objective C, iPhone | 1 Comment

30th June 2009

Dust and iAttractor full versions now free.

A couple of the first iPhone apps I made.

Dust

iAttractor

No ads, no cost. Enjoy.

posted in iPhone | 1 Comment

29th June 2009

Dot Notation or Square Brackets?

In Objective-C, you call methods with square brackets. Instead of:

C:
  1. myObject.myMethod();

it's:

C:
  1. [myObject myMethod];

Instead of:

C:
  1. myObject.myMethod(argument);

it's:

C:
  1. [myObject myMethod:argument];

Bizarre at first to many, but it really does grow on you. Especially with multiple arguments, it's like having named parameters. Compare code that looks like this:

C:
  1. myObject.setProperties(100, 100, 50, 50);

to this:

C:
  1. [myObject setPropertyX:100 y:100 width:100 height:100];

A contrived example, but you see how you always know what the parameters are.

Now, you can also set up getters and setters, by creating a private instance variable, and then either writing your own getters and setters or using @property and @synthesize (or a combination of both techniques).

In Objective-C, the getter name is the same as the private variable name, and the setter is "set" + the var name with initial cap. i.e. for variable, "stuff", you'd have public methods, "stuff" and "setStuff". So you can do stuff like:

C:
  1. int i = [myObject stuff];

and:

C:
  1. [myOtherObject setStuff:i];

But, at this point, you can now shortcut that with dot notation, which is much more familiar to many coming from other languages:

C:
  1. int i = myObject.stuff;
  2. myOtherObject.stuff = i;

At first, I was all over dot notation because I'm used to it. But as time goes on, I find myself seeing it as ugly. Mostly out of a respect for consistency. You wind up with stuff like this:

C:
  1. [myObject doSomething];
  2. myObject.x = 15;
  3. [myObject doSomethingElse:@"abc"];
  4. myObject.b = YES;

It starts to feel like you are coding in two different languages. So I've been making an effort to use only brackets. It's a bit more verbose, but looks a lot cleaner:

C:
  1. [myObject doSomething];
  2. [myObject setX:15];
  3. [myObject doSomethingElse:@"abc"];
  4. [myObject setB:YES];

There's one use case that bugs me though: += (and its kin). With dot notation, you're fine:

C:
  1. myObject.x += 10;

But you can't really do that with bracket notation. You wind up with:

C:
  1. [myObject setX:[myObject x] + 15];

Which just takes me back to Flash 4's getProperty/setProperty. Remember moving a movie clip around with:

Actionscript:
  1. setProperty(myMC, "_x", getProperty(myMC, "_x") + 1);

Ugh. Thought I had escaped stuff like that. :)

Anyway, for now, I'm going on a purist kick and avoiding dot notation altogether. I may drop back and be pragmatic about it after a while.

posted in Objective C | 11 Comments

28th June 2009

Flash on iPhone

No, I'm not predicting when it's going to be on there, saying it's never going to be on there, or forwarding any conspiracy theories about why it's not on there already. I'm just curious what people think of when they think of "Flash on the iPhone".

This started as a twitter conversation. But sometimes 140 chars just aint enough.

Basically, as I see it, there are two avenues that could be gone down.

1. A standalone Flash player that would run SWFs, maybe even an AIR type runtime that allowed you to save and load files to the system, etc. Custom chrome and windowing stuff isn't really an issue as all apps run full screen on the iPhone.

2. A Flash Player plugin for mobile Safari.

#1 I can see as being incredibly useful and usable. Make games and apps, install them to your phone and they run in the player. Fantastic! That would rock. Unfortunately, I also think that's the least likely to ever see the light of day on the iPhone.

A. It cuts right across Apple's policy about apps not being able to run external code (same reason the C64 emulator got shot down).

B. It cuts right across Apple's own App Store model.

So, #2, Flash Player in Safari. This I can see eventually occurring. In fact, I'd say this is almost inevitable, but wouldn't try to make any predictions on when.

This would be kind of cool, I guess, but I'm not all that excited about it. I wonder what people picture when they think of this. Suddenly, Safari on your iPhone will show all your Flash content, just like a normal browser? hmm... First of all, the iPhone's screen is 480x320. Take off the status bar and the Safari tool bar and you have about 480x270. Here's what a full screen existing Flex app will look like:

phone

I scaled the picture down a bit so that it was exactly the size of my iPhone when I held it up against my Mac Book Pro screen. That text is about  maybe 4 pixels high. So no, I'm guessing the vast majority of existing Flex and Flash web apps are not even going to be remotely usable in Flash in mobile Safari. Someone mentioned pinch and zoom and panning around. Sure, for some apps, that would work. But look at an app like the one above. I think that would be a horrible experience as well.

Now, I know that all of you out there who actually do mobile development are saying, "yes, of course, you have to design for mobile." I'm just not sure that everyone who is clamoring for Flash on the iPhone is thinking that far ahead. This means making a regular version of your Flash app and an iPhone version. Or, if you are really good, making an app with such awesome layout behaviors that it really does work good in both.

And what about all those sites that don't go ahead and take that extra step? Well, most of them are going to look like crap and be pretty unusable. Just like most of the regular HTML websites that don't make an iPhone version. I really only use mobile Safari when I absolutely have to. If what I want to look at isn't really vital, I'll just make a note to look it up when I get on a real computer.

Chuck Freedman Kevin Suttle (wow! they look alike) just brought up an excellent point, too (twitter is streaming by as I write this), about video. Yes, I'd love to be able to watch ALL flavors of Flash video content on my iPhone, not just what Youtube has converted to iPhone friendly versions. I wonder if that could be separated out somehow. Probably not, but would be a great step towards finally getting Flash there.

Anyway, I'm no expert in all these fields. Just wanted to expand my ideas, because on Twitter I started sounding like a Flash-hating iPhone fan-boy! :)

[EDIT]

A third possibility is now being tossed around on twitter - something that would bridge between Flash and Objective-C, possibly a tool that would convert AS3 / Flash / Flash byte code to Objective-C byte code. I guess Unity does something like this, spitting out an XCode project from your Unity project. Personally, I don't really see this as "Flash on the iPhone", but is an interesting possibility. And personally, I don't see it is as something I'd personally use. Whenever  you convert code over like that, you lose access to the low level APIs you'd normally have access to if you were just coding in the target language. Since I've already gotten over the major portion of the Objective-C hump, I'm not sure how much something like that would entice me. But I'm sure it would be very interestin for those who are scared of square brackets. :)

posted in Flash, iPhone | 27 Comments

28th June 2009

Bug Out! Submitted to App Store

http://wickedpissahgames.com/?page_id=105

posted in Objective C, iPhone | 10 Comments

27th June 2009

Bug Out! New iPhone Game Coming Soon!

Almost done. Hope to submit this weekend, along with a whole lot of other stuff I have to do. But figured I'd start getting the "buzz" out now. :)

posted in Objective C, iPhone | 9 Comments

24th June 2009

TextExpander and XCode (and Pragmatic Screencasts)

I installed TextExpander a few weeks back and have been slowly building up some cool snippets. One thing I often want to do is log something. An object, an int or float, or a point or rectangle. The object and numbers can be pretty easy, unless you are logging the result of some method call or something, but the point and rectangle are prime candidates for snippets. I went back and forth with doing this via Text Macros and doing it via TextExpander. In the end, I like the flow I have with TextExpander. Here they are:

logrect NSLog(@"%clipboard: %%f, %%f, %%f, %%f", %clipboard.origin.x, %clipboard.origin.y, %clipboard.size.width, %clipboard.size.height);
logpoint NSLog(@"%clipboard: %%f, %%f", %clipboard.x, %clipboard.y);
logfloat NSLog(@"%clipboard: %%f, ", %clipboard);
logint NSLog(@"%clipboard: %%i, ", %clipboard);
logobj NSLog(@"%clipboard: %%@ ", %clipboard);

As you see, I'm making use of the clipboard. So you select the item you want to log and copy it. Then type the shortcut and you're done.

For example, say I have a method named myRect which returns a CGRect. So I have some code that says [self myRect] and I want to know what that's returning. I select [self myRect], copy it, move to the line above or below and type logrect and I get:

NSLog(@"[self myRect]: %f, %f, %f, %f", [self myRect].origin.x, [self myRect].origin.y, [self myRect].size.width, [self myRect].size.height);

In fact, that's exactly what I just did while typing the blog post, since TextExpander works pretty much anywhere. :)

On the subject of Text Macros, which can be pretty damn powerful in themselves, I refer you to the Pragmatic Programmer site's Becoming Productive in XCode Screencasts. I'd seen this page before, but didn't think I wanted to pay for a couple of screencasts showing some shortcuts. Then someone highly recommended it so I took the leap. NO REGRETS! These are great. If you are a beginner or even intermediate XCode user, you will without a doubt find something that saves you $10 worth of your time in there. Some great stuff on Text Macros. Again, the above could have been done with macros, but not sure they could have used the clipboard. You could access the selected text I guess, but then you'd have to either use the menu to select the macro, or assign some shortcut to it. With my snippets, it's select, copy, type, all keyboard.

posted in Objective C, iPhone | 1 Comment

23rd June 2009

From Hossgate to Hughesgate

So the big news today on Twitter was Chris Hughes' talk at TED. He got just under 2 minutes on stage and showed off some augmented reality stuff using Papervision 3D and the FLARtoolkit. Unfortunately he said some stuff along the lines of "I wrote" and "we converted" and didn't mention the actual projects themselves by name. Understandably, some of the Flash community, who have contributed or use these projects, were pretty upset about this. A lot of people have put a lot of time in on these projects and then to see them on stage at a big name conference like TED, without being mentioned by name, and in a way that implies that another person did it all... yeah, not fun.

Now, I happened to meet Chris out at 360iDev earlier this year in San Jose. We didn't become good friends or anything, but we had several conversations and hung out a bit. I liked him. Interestingly enough, the one thing we talked about, pretty much exclusively, was open source. Now, I'm all for open source, but Chris actually struck me as an open source fanatic. He's created open source projects and actively contributes to others. He's very serious about it. In fact, we wound up talking to the 360 organizers and set up an impromptu lunch discussion panel one day to talk about open source and how it fit in with the iPhone platform.

So my initial reaction was that it didn't make sense that he'd be up there maliciously trying to claim other people's work as his own. It just seemed incongruous to me. However, he said what he said, and it definitely comes off sounding like he created this whole thing. I could go into saying how he only had 2 minutes, and little preparation, and whatever. My point is not to stand up for him or defend him or apologize for him. He can do that for himself. And for the record, he did post on his blog the fact that he used Papervision and FLARtoolkit - before all the uproar - and has since blogged explaining himself.

My real reason for writing this is that it really depressed me how ugly things got in the community. I must have gotten 100 or more tweets about the situation. There were blog posts, jokes. People were posting photoshopped photos of Chris. Someone even started printing tshirts!!! For god's sake! And before that, nobody even talked to the guy, asked him what was up.

Now, again, I want to re-iterate: I'm not here to defend him. And I totally understand why certain people would be upset. But this whole thing got way more ugly and disturbing than it really should have. I compared it to a lynch mob, and to me, that's really how it felt.

How can I not compare this to last week's Hoss/Flashbelt turmoil. The sad thing was that many of the same people who were decrying the whole "bandwagon jumping" to defame Hoss were now jumping on that same bandwagon to defame Chris. I know, I know, "it's different." Well the facts are, but the reaction is not.

My one question was, why not just talk to him first? Several people answered that simply talking to people does not always work. Frankly, that scares the crap out of me. "I don't like what Joe is doing. I'm not going to talk to him because that might not work, so I'm going to start a massive PR campaign against him." I'm not naming names, because most of the people who were going on about this are actually very good friends. People who I have massive respect for.

I'm not sure what to make of it all. It gets me down though. :(

posted in Conferences, General | 27 Comments

21st June 2009

Fireworks: Can someone explain this, please?

I love Fireworks, but this has bugged me since I've been using it. Say I draw a line. It's a 1-pixel (I'm zoomed way in), hard, black line. Notice the blue vector line and end points, and the position of the line in relation to the underlying vector:
line_before

But since I was drawing it by hand, maybe it's not quite as long as I wanted it. It's 10-pixels long, but I wanted it to be 11. No problem. I go into the properties inspector and change that 10 to an 11. Now I get this:

line_after

It's no longer centered on the vector line, and the line itself has shifted down and to the right. And there's no way to get it back to that state.

But it gets worse. Say I drew a red rectangle and then drew a line on the bottom of it. Like so:

before

Now, you see the line says that it is 10 pixels wide. And it is the same width as the rectangle. But let's select the rectangle.

before2

Wait, the rectangle is 11 pixels and the line is 10 pixels? But they are the same size. Well what happens if we go into the properties inspector and change the width of the line to 11. It should match the rectangle, right?

after

OK, now it's not even on the bottom of the rectangle anymore. It did that weird shift thing. Well, we'll just nudge it back into place...

after2

GAH! That's All wrong! Now it says it's the same size as the rectangle, but it's longer!

Usually about this time I throw away the lines and start drawing one pixel thick rectangles. This is fine as long as they are perfectly horizontal or vertical. But not so much if they are at all diagonal.

I've been using Fireworks for at least 4 or 5 versions now, and this has always made me crazy. I have to believe that I'm just missing something. Surely line drawing couldn't be that messed up in such a major tool and not be fixed for this long...?

SOLVED!

Link given in comments:

http://kb2.adobe.com/cps/217/d6f2172a.html

Probably more info than I can take in all at once, but at least I know I'm not just going crazy.

posted in General | 10 Comments

19th June 2009

KClipper: Save Text Clips to your Kindle

A couple of months ago I got my Kindle 2. I was a bit skeptical, but fell in love with it. Even then, I thought, well, it's new and shiny, see how much you like it in a few weeks. I still love it. In addition to books, I found it was a great tool for reading stuff later, such as blog posts or articles you see on the web. Of course you can subscribe to blogs (for $$$) and you can set up Instapaper to send stuff to your Kindle, and there are other services that also allow you to subscribe to and send blogs to your Kindle. These work through the Kindle conversion process, which is going to cost you $0.15 per megabyte or any part thereof. Not a big deal in the big picture. And there is the convenience of having it go straight to the device wirelessly.

But I found myself often seeing an article on the web that I wanted to check out later on the commute or whatever. The Kindle happily accepts plain text files, so I found myself just copying the text of the article, opening Text Edit and pasting it in, and saving it to the Kindle. Worked great. But my Kindle isn't always plugged in. So I started saving the files in a folder and then later when I connected, I'd just drag the contents of the folder into the Kindle documents folder. Then I thought, hmmm... saving text to a text file in a specific directory and then copying all the files in that directory to another directory... that's something a simple computer program should be able to handle. And so, KClipper was born.

kclipper

Here is a rough feature / non-feature list:

  • KClipper (pronounced "kay clipper") is made with Adobe AIR, so it should run fine on Mac or Windows (though I've only tested it on my Mac.
  • It's FREEEEEEEE!
  • Your Kindle does not need to be connected to copy and save articles.
  • Your Kindle DOES need to be connected to transfer the articles to the Kindle itself.
  • In other words, this does not use email or wireless, which also means that it won't cost you a dime.
  • Currently, KClipper only supports plain text. So no fancy formatting. No images.

Here's how it works. You see something you want to read later. You select the text, copy it, open KClipper and paste the copied text into the left pane. KClipper reads the first line of the text as a title for the article, so you can edit that if it doesn't reflect what the article is about. You hit "save" and the article is saved to your hard drive, in a KClipper Articles directory. The first time you use the program, you'll be asked to choose a directory to store your articles in. You can change that any time through the preferences.

You can save as many articles as you want. Read them again right in the KClipper UI if you want. Mark them up, edit them, delete them if you change your mind about them. I don't know of any particular limit on article length. I guess whatever the AIR text field will support. Most likely good enough for even a very large blog post. Not sure if you'd be copying and pasting War and Peace anyway.

So now you're going to hit the road after a long day of saving articles from your favorite web sites. You plug in your Kindle and hit "sync". Bam. All your articles are now on your Kindle. The first time you sync, you'll be asked to specify your Kindle documents directory. Simply browse to your Kindle. There you'll see a directory named "documents". Choose that, and you should be all set from there on out.

If you didn't make it through that explanation, hit play, sit back and let me babble incoherently to you, while watching the pretty pictures.

That's it. Pretty darned simple. In fact, so simple, that I've put off releasing it for some time. I actually created the program shortly after I got my Kindle, almost a couple months ago. Then I started invalidating it. I mean all it does is save files to a directory and then copies them to another directory. But I realized that I'm still using it on a regular basis. Furthermore, I haven't needed to fix anything or update it at all since I finished programming it. It's so simple, it just does what it does and works. Anyway, if it's useful to me, it might be useful to others too. If not, hey, it's free. Delete it is it's wasting disk space and move on.

Here's the link to the installer.

KClipper

Two things:

1. Again, it's an Adobe AIR program. So if you have some big irrational beef against Adobe or AIR, move along.

2. This means you'll need the Adobe AIR runtime installed on your computer. Get that here. I could have done the whole installer badge thing, which would have auto-installed AIR for you if you didn't already have it, but we're all big boys and girls here. I'm sure you can manager two installs in one day.

OK, I lied. Three things.

3. When you go to install it, it's going to tell you that it's an unsigned app, and ask you if you want to trust it. I don't know much about app signing. Apparently I'd need to go to some third party certificate vendor and pay them money for them to say that I am I'm not installing a virus on your computer. Whatever. I didn't do that, so you'll get this big warning that seems to imply that I AM going to do something bad to your computer. I'm not, but if this scares you, don't install it. No hard feelings.

posted in Apollo, Flash, General, Kindle | 8 Comments

Who is reading BIT-101?

Copyright ©2009 by Keith Peters. All rights reserved. This means that you man not reprint or repost the contents of this site without express written permission of the author.