Problems with variables in Obj-C - Printable Version
+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Problems with variables in Obj-C (/thread-3842.html)
Pages: 1 2
Problems with variables in Obj-C - vnvrymdreglage - Oct 1, 2006 08:03 PM
I've been playing with Objective-C and Cocoa for quite a while now, but I'm just now beginning to really learn. Anyways, I made a little test program to read tile values from a string (mapl) and use a 'for' loop to draw each tile in the string across the top row of my NSView. A 1 represents a grass tile and a 2 represents a tree tile.
However, when I run it, everything is covered in tree (2) tiles, instead of being grass, tree, grass, tree (1212) like in the string. Any ideas of what is wrong? I think my switch statement is executing all of the code for some reason instead of just executing the corresponding case.
and also :
Problems with variables in Obj-C - akb825 - Oct 1, 2006 08:52 PM
A few suggestions:
Do yourself a favor and only load the images once rather than every time you draw. Also, tile01, tile02, nextTile, and map1 are all leaked every single call to draw. That's... not good. For nextTile and map1, you have the further problems that you're allocating space, then throwing them away immediately by assigning them to something else. Whenever you use = on a variable, that's essentially throwing away what used to be there, and in this case, it leaks memory.
For your loop, instead of having just 13, you should use [map1 length]. Instead of making a substring with a particular range, it would be best to just use [map1 characterAt:i] and subtract '0' to that value to convert from ascii to an actual number.
Problems with variables in Obj-C - vnvrymdreglage - Oct 1, 2006 09:49 PM
Thanks a lot for the advice. I'm still stuck on a few things. Sorry if these are total newbie questions, but I'm getting the hang of it.
Using nextTile = [mapl characterAt:i]; generates a warning that NSString may not respond to characterAt: and brings up an error and the debugger when I run the program. I tried using the existing substring method and subtracting 0 from the resulting value but again, error.
As far as loading my images and variables goes, should they be loaded once in a seperate routine and then released when the application terminates? And for mapl, should I use a custom initializer to declare the string's value at initialization? What about nextTile that constantly changes?
On the bright side, [mapl length] did work. I'm coming from a background in BASIC and Visual Basic, so memory management is a tough subject for me, but it's starting to make more sense. If anyone wants me to upload the XCode project to take a look at it, let me know. I'd like to try and learn as much as I can on my own though : )
Problems with variables in Obj-C - Steven - Oct 1, 2006 10:19 PM
The method you're looking for is characterAtIndex:
Give that a go.
The API docs will be a lifesaver - for example, if you want the documentation for NSString you can option-double-click on NSString in XCode and it will look up the class for you.
Problems with variables in Obj-C - akb825 - Oct 1, 2006 11:03 PM
Oops, sorry, yeah, I got that name wrong. I got that from the docs, but I guess I forgot to put in the last part... :bllush:
Anyway, the docs are very helpful indeed. The 2 main pages you will need to look at are this and this.
To answer your other question, tile01 and 02 should be stored as class member variables (declared between the curly braces in your .h file) and should be initialized in your initWithFrame method. You should also declare your own dealloc method, where you release those variables.
For map1, simply saying "NSString *map1 = @"...";" is sufficient: that's a literal constant that will be stored in the executable itself. It's automatically created on launch and destroyed (in memory) at exit. You might also want to look into using regular C strings for things such as this, though. Since they're really just arrays, you can do anything with them that you could with arrays. For example, instead of
NSString *map1 = @"...";
you would have
const char *map1 = "...";
Then, instead of doing
nextTileNum = [map1 characterAtIndex:i] - '0';
you would simply do
nextTileNum = map1[i] - '0';
If anything, you would at least get less overhead. I also like C strings since you can do whatever you like with them, including editing the contents, assuming you have enough space allocated. Be careful, though: if you use a literal string (with "") it's put in protected memory. You need to use something like strcpy to copy the string, or strdup to duplicate it. (the resulting string with strdup is in allocated memory, though, so you'll need to free it; strcpy, however, can be placed in pre-allocated memory, such as a simple static array that doesn't need to be freed)
I guess this last part leads to my next suggestion: you should probably learn C. It will teach you a lot of what you need to know with the lower-level portions of ObjectiveC, and also it can teach you a lot about memory management without getting into all the different conventions and rules with ObjectiveC objects. (though you can usually bend ObjectiveC to your will and use a sort of C-style memory management if you know what you're doing; I tend to do that myself: I never retain an object and I set it so I only need to call release once)
Problems with variables in Obj-C - Malarkey - Oct 1, 2006 11:09 PM
vnvrymdreglage Wrote:However, when I run it, everything is covered in tree (2) tiles, instead of being grass, tree, grass, tree (1212) like in the string. Any ideas of what is wrong? I think my switch statement is executing all of the code for some reason instead of just executing the corresponding case.
Um, I don't think anyone's pointed this out yet but your case statements need to be terminated with a break statement like so:
Otherwise, when you jump to one case, it'll just fall through to the cases after it.
Problems with variables in Obj-C - Steven - Oct 1, 2006 11:31 PM
I'd recommend against mixing C strings and NSStrings unless you have a very good reason to. Keeping track of which is which is likely to be more trouble than it's worth, especially if you don't have your mind wrapped around things like memory management and stuff yet. Use NSString when you want a constant string, and NSMutableString when you need to use its extra functionality. It will save you a lot of headaches. Know the rules before you break them
Problems with variables in Obj-C - Blacktiger - Oct 2, 2006 08:49 AM
Malarkey Wrote:Um, I don't think anyone's pointed this out yet but your case statements need to be terminated with a break statement like so:
Indeed, if you don't put the break at the end of case 1, then you fall through to case 2 which draws your tree over your grass. Additionally, both draw 1 and draw 2 are put into the log for the same reason, if you look at the log output you will notice double the number you should be expecting. Edit: Actually you have about 20 log outputs which is > 13 and less than 26 since you draw only tile 2 sometimes.
Problems with variables in Obj-C - vnvrymdreglage - Oct 2, 2006 02:08 PM
Awesome, the break; statements fixed everything. I'll try some of the other suggestions you all gave me as well, but at least it's working right now. Thanks everyone! I'll post back later if I have any more issues.
Some changes I'd like to make :
- fix the memory leaks
- support a whole screen full of tiles ( I guess using x,y would be the best way? )
- support up to 9 different tiles (1 through 9)
- use an array of NSImage objects for the tiles instead of a large switch statement
I'm already building a nifty tile-based RPG engine in Visual Basic and I'm trying to carry over some of the similar features and methods I used.
Also, using characterAtIndex:i causes the program to crash for some reason. It gives me OpenEdit has exited due to signal 10 (SIGBUS).
Problems with variables in Obj-C - akb825 - Oct 2, 2006 02:24 PM
Are you sure you're using characterAtIndex with map1 rather than nextTile? (which is no longer needed) Also, you should use indexing with 0 to 9 instead of 1 to 9; you can also use an array of images instead of the switch statement with that system.
Problems with variables in Obj-C - vnvrymdreglage - Oct 2, 2006 02:51 PM
akb825 Wrote:Are you sure you're using characterAtIndex with map1 rather than nextTile? (which is no longer needed) Also, you should use indexing with 0 to 9 instead of 1 to 9; you can also use an array of images instead of the switch statement with that system.
Yes, I had nextTile = [mapl characterAtIndex:i]; I also tried characterAtIndex:2 to make sure it wasn't just a problem with 'i'. It still gives me an error. As for not needing nextTile anymore after it's converted, should I release the variable? What happens during the next loop cycle when it needs to use it again?
Problems with variables in Obj-C - akb825 - Oct 2, 2006 02:53 PM
Can you show me all the code that has to do with map1? It's likely you're doing something that destroys the string that you put in there.
Problems with variables in Obj-C - vnvrymdreglage - Oct 2, 2006 04:22 PM
I could upload the XCode project if you like. And by the way, it's mapL, not map1. I know it looks like a 1 on here though : ) And yet another question : to put my NSImages into an array, do I need to create an NSArray object?
Problems with variables in Obj-C - akb825 - Oct 2, 2006 06:52 PM
You took out the characterAtIndex: call, so I can't really debug that problem. However, one thing that I will say, is you need to take out both your [[NSString alloc] init] calls. That memory is never being used, since you then assign mapl and nextTile to different values afterwards, that memory you allocated is never touched.
To put the values in an array, you don't need to use an NSArray. A regular array will do fine. Between the curly braces in your .h file, declare this:
If you decide later to have 10 tiles, replace the 2 with a 10. Then, in the initWithFrame method, you should set tile01 into index 0 and tile02 into index 1. Then, change mapl to alternate between 0 and 1, and just us the index that you grab from the string. Create a dealloc method, then, and release all the objects in the array.
If you have further problems, posting the project would help.
Problems with variables in Obj-C - belthaczar - Oct 2, 2006 07:07 PM
I will echo akb825's statements that you don't really need to allocate memory for either nextTile or mapl since these both get assigned to temporary strings created elsewhere. In fact you could just say
The reason why you were having trouble with characterAtIndex: is because you were trying to assign its return value to an NSString variable. characterAtIndex: returns a unichar, which is essentially an unsigned short int. So something you could do instead is
Another handy Cocoa trick is