How to properly code "init" method in Objective-C, prevent "Expression result unused" warning - objective-c

I was given a main by my professor that I have to make the .h and .m files for in Objective-C using Xcode. I have it almost done but have two warnings that I can't figure out how to get rid of, "Expression result unused". The errors have to do with my init method for making an array of size 100. Here is where the main creates an object and then calls the method I have coded improperly, this part is given from my teacher and I can't change it:
// main.m
// ChutesAndLadders
#import <Foundation/Foundation.h>
#import "ChutesAndLadders.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
ChutesAndLadders *cl = [[ChutesAndLadders alloc]init];
[cl initBoard];
[cl makeChutes:10];
[cl makeLadders:10];
int chutes=0;
int ladders=0;
for(int i=0;i<cl.board.count;i++){
NSString * cell = (NSString *)[cl.board objectAtIndex:i];
int additionalSpaces = (int)[cl addToMove:cell];
if(additionalSpaces>0)
ladders++;
else if (additionalSpaces<0)
chutes++;
}
[cl printBoard];
}
return 0;
}
Here is relevant parts of my method:The error is from the "initBoard" method above, and "initWithCapacity" line below. I know that the two warnings are describing the same error. The code below is mine so I can change it, unlike above.
#synthesize board = _board;
-(id) initBoard
if((self = [super init]){
[board intiWithCapacity: 100];
for(int i = 0; i < 100; i++){
[board addObject:#""];
}
}
return self;
}
and here is the relevant code from my declaration of "board" in the .h file:
#interface ChutesAndLadders : NSObject{
#private
NSMutableArray * board;
}
#property (readwrite, retain) NSMutableArray *board;
-(id) initBoard;
I have tried a lot of small changes in syntax but to no avail. Please don't tell me the solution directly, but a nudge or a shove in the right direction I think is all I need and I will post the solution once I figure get it.
Pseudo solution:
#synthesize board=board;
-(void) initBoard{
_board = [board initWithCapacity: 100];
for(int i =0; i < 100; i++){
[_board addObject:#""];
}
}
This eliminated one of the warnings, but my program is not running properly so I still have work to do in other methods. This specific question as been addressed though and I have a better understanding of how this is working now.
Actual Solution
#synthesize board=_board;
-(void) initBoard{
_board = [NSMutableArray arrayWithCapacity:100];
for(int i =0; i < 100; i++){
[_board addObject:#" "];
}
}
This is the one that finally worked per Hermann. I swear that I tried this once and it didn't work, so I kept playing around and changing things(messing it up more) and then eventually got back to this and it of course worked. Xcode lies sometimes I think to irritate me.

Edit because at first I overlooked something:
Simply use:
ChutesAndLadders *cl = [[ChutesAndLadders alloc]initBoard];
because within initBoard you are calling [super init] anyway.
Does your professor try to trick you?
It is difficult to say without having a look at all of the code.
You are synthesizing a property board which has the iVar _board.
Meaning you can access it's getter or setter respectively by self.board or [self board] or [self setBoard: ...].
But within the initBoard method it is accessed differently:
[board intiWithCapacity: 100];
Despite the fact that we do not see where board is actually allocated and that the result of the initWithCapacity method is not used, I am asking myself what board actually is. It is not the property (that would be self.board etc) nor is it the iVar (that would be _board).
Apparently just board refers to the private iVar that you declared. But
#synthesize board = _board;
creates an iVar with the name _board of the same type (NSMutableArray*).
Therefore in your method, board is different from _board.
Althoug I am editing this for the 3rd time now, I am still not getting it. The .m file was given by the teacher and you have to create a matching .h file, right? In that case you should go for
#private
NSMutableArray * _board;
Well, that is done automatically anyway but writing it with "_" would avoid the creation of a similar named iVar and therefore avoid likely errors.
Background AFAIK: Theoretically or even practically init may create a different instance than the one that alloc created. Therefore you should always use the return value of init.
In general - independent from the strange objective-c notation around object initialization - when ever a method returns a value, then
[object method];
is syntactically correct, runs fine and everything but the return value is unused. And that is what your warning message is all about. Even if you assign it to a dummy object like
SomeClass *someObject = [object method];
you would get the warning that `someClass' is an unused variable.
Last edit:
You are nearly there. However, this is a shortcut for current versions of Obj-C, not for older ones:
.h file:
#interface ChutesAndLadders : NSObject
#property (readwrite, retain) NSMutableArray *board;
-(void) initBoard;
#end
.m file:
// omitting #synthesize forces the compiler to autosynthesize. In that case it is named "_board"
-(void) initBoard
_board = [NSMutableArray arrayWithCapacity: 100]; // this implies the alloc
for(int i = 0; i < 100; i++){
[_board addObject:#""];
}
}

You're returning something that you're not using. Also read up on writing proper constructors/initializing objects in Objective-C.

As Hermann said you should do
ChutesAndLadders *cl = [[ChutesAndLadders alloc]initBoard];
and then in your initBoard method
self.board = [NSMutableArray alloc] intiWithCapacity: 100];

You are not following standard Objective-C conventions, and that gets you trapped.
You have an instance variable board. Objective-C convention is that all instance variables should start with an underscore character.
You have a property board, and #synthesize board = _board. The synthesize creates an instance variable with an underscore character, named _board. Now you have two instance variables: board and _board. One of them, _board, is the instance variable backing the board property. The other, board, has nothing to do with board property at all.
And then somewhere you have a harmless looking but fatal statement board = whatever. Which assigns to that totally useless instance variable board. Not _board, but board. If you wrote _board then you would be following Objective-C conventions: Assignment to instance variable using highly visible name. or self.board which would be the property.
And [board initWithCapacity:100] doesn't do anything. First, because the board instance variable (totally unrelated to board property or _board instance variable) hasn't been allocated. It's nil. Sending initWithCapacity to nil does nothing. Sending addObject to nil does nothing either.

Related

Items disappearing from array within array

I create a NSMutableArray that I need as long as my app lives, lets call it suseranArray, just after the #implementation of my main class. This Array will hold several objects of a class called Vassal. A Vassal is simply:
1) A NSMutableString
2) Another NSMutableString
3) A NSMutableArray
4) Another NSMutable Array
Each Vassal created is also needed for the life of the app, and they never change.
These objects are made as (retain) properties in an .h file, synthesized in the .m file, and each given an alloc+init whenever the object Vassal is created during the init function. Each vassal has data filled in and stored in the suzerain Array. the 3rd item always has several elements, and after a bug appeared, I put a line to check if it is ever empty, but it never is, and life is good.
Now, later on when a certain Vassal object is needed, we try to access its 3rd property to fetch the data in there, and sometimes that array empty... I checked to see if it disappeared somehow, but it is always there on the debug, carrying a nice address like 0x2319f8a0 which makes sense since the NSMutableString just above it is at address 0x2319fb40 - (I was expecting 00000000 after a lot of headache). What is happening? I my head, I am creating an RETAINed objects, which retains data put in by default, and that object is put inside another, but somehow the data inside the array vanishes. What possible scenario could lead to this? Thank you for your time :)
Note: the last array currently just holds one item at this stage of development, and curiously enough, that one item is never missing, despite the two arrays being 'brothers'
Vassal.h
#interface Vassal : NSObject
#property (retain) NSMutableString *wordBody;
#property (retain) NSMutableString *wordCode;
#property (retain) NSMutableArray *wordRelations;
#property (retain) NSMutableArray *wordLinks;
#end
Vassal.m
#implementation Vassal:NSObject
#synthesize wordBody;
#synthesize wordCode;
#synthesize wordRelations;
#synthesize wordLinks;
-(NSObject*) init
{
if(self=[super init])
{
wordBody=[[NSMutableString alloc] init];
wordCode=[[NSMutableString alloc] init];
wordRelations=[[NSMutableArray alloc] init];
wordLinks=[[NSMutableArray alloc] init];
}
return self;
}
//Somewhere in Suseran:
-(void)fillStuff
{
...
Vassal *vassal=[Vassal new];
for (int i=0;i<[originalDataString length];i++)
{
...
[vassal.wordRelations addObject:anItem];
...
}
int errorTest=[vassal.wordRelations count];
if (errorTest==0)
{
//breakpoint here. Program NEVER comes here
}
[bigArrayOfVassals addObject:vassal];
}
//these arrays are never touched again but here:
-(void) getVassalstuff:(NSMutableString*)codeOfDesiredVassal
{
Vassal *aVassal;
for (int i=0;i<[bigArrayOfVassals count];i++)
{
aVassal=bigArrayOfVassals[i];
if ([codeOfDesiredVassal isEqualToString:aVassal.wordCode)
{
int errorTest=[aVassal.wordRelations count];
if (errorTest==0)
{
//yay! this breakpoint sometimes is hit, sometimes not,
//depending on code's mood. Why is this happening to me? :,(
}
}
}
}
I see that that you have properties that are mutable (which is itself a bad idea except for specific cases) and that you are retaining them.
Mutability means that if you have set the array as a property based on some other array, and if that original array is changed, the array in your property is also changed. It may be, and I don't know because you haven't shown any code, that you are emptying the original array, and thus changing the array you have as a property
Solutions:
My preferred solution is to use the immutable versions of these classes for your properties; NSString, NSArray and instead of retain use copy
A second solution is to leave the properties as mutable, but write a custom setter for each of them that stores a mutableCopy of the object that you pass in.
In both of these cases, your property will be a copy of the object used to set the property, so that if the object is changed outside of your class it will not affect your class's properties.
edited to add, after a comment
If you declare your property as
#property (copy) NSArray wordRelations;
Then simply writing
vassal wordArray = tempArray;
will do the same thing and is cleaner and more readable..

debugging objective c memory leak with xCode Leaks

I'm doing my first steps in finding memory leaks in xCode 4.5 and using the Leaks instrument. I found a couple of issues and seemed to fix them, but this one eludes me.
Here is the code:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo->name = nm;
[imgInfo->name retain]; // I'm using it outside of this method
Leaks reports a leak in the second line, with the percentage next to the "i" at %100.
So I tried two things:
One, I marked nm with autohrleas like this:
NSString *nm = [[NSString stringWithUTF8String:img->name.c_str()] autorelease];
Two, I also tried calling release on nm after it's assignment to imgInfo->name so the code looks like this:
imgInfo->name = nm;
[imgInfo->name retain];
[nm release];
But in both cases the app crashes with BAD_ACCESS when I run it, and call [imgInfo->name UTF8String].
What am I missing?
EDIT following Rob's answer:
This is the RUBEImageInfo class:
#import "cocos2d.h"
#interface RUBEImageInfo : NSObject {
#public CCSprite* sprite; // the image
#public NSString* name; // the file the image was loaded from
#public class b2Body* body; // the body this image is attached to (can be NULL)
#public float scale; // a scale of 1 means the image is 1 physics unit high
#public float angle; // 'local angle' - relative to the angle of the body
#public CGPoint center; // 'local center' - relative to the position of the body
#public float opacity; // 0 - 1
#public bool flip; // horizontal flip
#public int colorTint[4]; // 0 - 255 RGBA values
}
#end
And the .m:
#import "RUBEImageInfo.h"
#implementation RUBEImageInfo
// Nothing much to see here. Just make sure the body starts as NULL.
-(id)init
{
if( (self=[super init])) {
body = NULL;
}
return self;
}
-(void) dealloc {
[name release];
[super dealloc];
}
#end
A couple of reactions:
Instruments identified where the leaked object was allocated, but in this case, this code might not be the source of the leak. You should:
ensure you release the name in the dealloc method of RUBEImageInfo; and
also, if you're setting name a second time, make sure you release the previous name object before you set it to a new object.
Your life will be much easier if you use declared properties rather than dereferencing class instance variables. For example, if name was declared as:
#property (nonatomic, copy) NSString *name; // you could use `retain`, too, but `copy` is safer when dealing with strings
Then you would set the name property as so:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo.name = nm;
// this is no longer needed as the `name` setter will take care of memory semantics
// [imgInfo->name retain]; // I'm using it outside of this method
By using the setter accessor method (i.e. the "dot syntax" of imgInfo.name), it will take care of a lot of routine memory semantics of releasing any previous object that name may have referenced, and it will do the necessary copy or retain. Obviously, the RUBEImageInfo method dealloc still needs to release name, but at least it simplifies the memory semantics of the name property of RUBEImageInfo objects.
Since you are using manual reference counting, I'd encourage you to investigate the "static analyzer" (invoked by selecting "Analyze" from Xcode's "Product" menu). The Leaks tool in Instruments will tell you what leaked, but it doesn't tell you where the leak happened; it has no way of knowing; it can only show you where the leaked object was allocated and you'll have to hunt down the logic error yourself. The static analyzer can sometimes point out errors that lead to leaks, but more importantly, show you where the leak was caused, rather than just where the leaked object was originally instantiated. You should have a clean bill of health from the static analyzer before you even bother running Instruments.
Looking at your code sample, if you're not going to use declared properties (not sure why you wouldn't, as it makes life easier, but to each his own), I'd suggest making sure you initialize all of your objects in init and release all of them in dealloc:
#implementation RUBEImageInfo
-(id)init
{
if ((self=[super init])) {
body = NULL;
name = nil;
sprite = nil;
// I might initialize other class instance variables here, too, but that's up to you
}
return self;
}
-(void) dealloc {
[name release];
// shouldn't you release `body` and `sprite`, too?
[super dealloc];
}
#end
Then your code that sets the name instance variable would make sure to release the previous object before setting the new object. Thus the initial instantiation might look like:
RUBEImageInfo* imgInfo = [[[RUBEImageInfo alloc] init] autorelease];
NSString *nm = [NSString stringWithUTF8String:img->name.c_str()];
imgInfo->name = [nm retain]; // retain the new object
But if you update it later, you should:
NSString *nm = [NSString stringWithUTF8String:someNewImg->name.c_str()];
[imageInfo->name release]; // release the old one
imgInfo->name = [nm retain]; // retain the new object

Traversing a NSMutableArray?

To start let me tell you I am a total Objective-C beginner. This is my problem:
I have a NSMutableArray that stores objects, (Player) that has the name of the player and his/her score.
I am able to add objects to the array using addObject, but I am having trouble traversing this array. This
is how I do it:
// Get the reference to the array
NSMutableArray *myarray = [delegate getArray];
// Create a numerator
NSEnumerator *e = [myarray objectEnumerator];
id object;
while (object = [e nextObject])
{
[object printPlayer];
}
The method printPlayer belongs to the Player class and it just prints the name and the score.
The problem is when I have three players in the array and I am trying to print the content, it reaches this error inside the printPlayer method:
Thread 1: EXC_BAD_ACCESS(code=1, address=0x0000008)
Strangely if I use NSLog(#"%#", object); instead of [object printPlayer]; it prints a reference to the object and does not reach any error.
Anyone could point me what could be the problem when I try to use [object printPlayer]
Cheers
Update 1:
This is my printPlayer method:
-(void) printPlayer
{
NSLog(#"\n\nName: %#\nScore: %d", playerName, playerScore);
}
Update 2:
Player.h:
#interface PROGPlayer : NSObject
#property (nonatomic, assign) NSString *playerName;
#property (nonatomic, assign) int playerScore;
-(id) init: (NSString *) n;
-(void) printPlayer;
#end
Player.m:
#import "PROGPlayer.h"
#implementation PROGPlayer
#synthesize playerName;
#synthesize playerScore;
/**
* Player's class constructor
* #param n Player's name
* #param s Player's score
*/
-init: (NSString *) n
{
if (!(self = [super init])) return nil;
else
{
playerName = n;
playerScore = 0;
}
return self;
}
-(void) printPlayer
{
NSLog(#"\n\nName: %#\nScore: %d", playerName, playerScore);
}
#end
It seems like your problem is in the way you're defining your properties.
You're using assign rather than strong, or copy.
In a nutshell, it's because strong implies that you want your object to be retained.
Using copy implies that you want to create a new copy of an object or a value and set that as value of your property... As Mario and Jarsen explain, using copy is better practice when working with arrays to prevent the array being mutated (i.e. values changed) while it is being enumerated / traversed. Using copy also retains the new object.
If you're using ARC and your objects are not retained, then they will be released automatically by the compiler.
Using assign means that you assume the new object has been retained elsewhere and that you don't want to retain it again.
I suppose what was happening is that you were assigning your variable to your property, but the variable was being released (and hence resulting in nil) and causing the crash.
Here are a few links:
New to Objective C: Need help understanding strong reference vs assign
Objective-C ARC: strong vs retain and weak vs assign
Clarification on assign, retain, copy, strong?
Your playerName property should best be copied instead of assigned
#property (nonatomic, copy) NSString *playerName;
When trying to access the assigned value, the object most likely is gone causing the bad access.
Also remember to release playerName in dealloc when you set the property to copy.
Cheers
You just want to enumerate the array?
for (CustomClass *object in myArray){
[object printPlayer];
}
Either what Mike Z said or the "crude":
for (int i = 0; i < myArray.count; i++) {
CustomClass* object = [myArray objectAtIndex:i];
[object printPlayer];
}
While there are more elegant schemes, you can clearly understand what this one is doing, and how an NS(Mutable)Array is just a simple analog to a standard C array.

Class variable defined at #implementation rather than #interface?

I'm new to Objective-C, but I am curious about something that I haven't really seen addressed anywhere else.
Could anyone tell me what is the difference between a private variable that is declared at the #interface block versus a variable that is declared within the #implementation block outside of the class methods, i.e:
#interface Someclass : NSObject {
NSString *forExample;
}
#end
vs.
#implementation Someclass
NSString *anotherExample;
-(void)methodsAndSuch {}
#end
It seems both variables ( forExample, anotherExample ) are equally accessible throughout the class and I can't really find a difference in their behaviour. Is the second form also called an instance variable?
The latter is not defining an instance variable. Rather, it is defining a global variable in the .m file. Such a variable is not unique to or part of any object instance.
Such globals have their uses (roughly equivalent C++ static members; e.g. storing a singleton instance), but normally you would define them at the top of the file before the #implementation directive.
They're very different! The one in #implementation is a global variable not unique to each instance. Imagine there were accessors for both variables, written in the obvious way. Then the difference in behavior is shown here:
Someclass* firstObject = [[Someclass alloc] init];
Someclass* secondObject = [[Someclass alloc] init];
//forExample is an instance variable, and is unique to each instance.
[firstObject setForExample:#"One"];
[secondObject setForExample:#"Two"];
NSLog(#"%#",[firstObject forExample]); //Result: "One"
NSLog(#"%#",[secondObject forExample]); //Result: "Two"
//anotherExample is a global variable, and is NOT unique to each instance.
[firstObject setAnotherExample:#"One"];
[secondObject setAnotherExample:#"Two"];
NSLog(#"%#",[firstObject anotherExample]); //Result: "Two" (!)
NSLog(#"%#",[secondObject anotherExample]); //Result: "Two"
//Both instances return "Two" because there is only ONE variable this time.
//When secondObject set it, it replaced the value that firstObject set.
If you are looking for this sort of behavior, you might be better off using a class variable, like this:
static NSString* yetAnotherExample = nil;
Then you can use class methods to interact with the variable, and it's clearly class-specific (as opposed to instance-specific or global).
If you declare a variable inside the #implementation section, you're actually creating a global variable, visible everywhere (in every method in your application).
Member variables can only be declared in the #interface section. They are only accessible in the class itself.
The private block declared inside the #implementation block is kind of dangerous, seems to me, comparing with other OOP concept e.g. Java. Its look like member variable but kinda static.
Novice programmer can easily fooled with it. I write a test program and surprised with the behaviour.
#interface SomeClass : NSObject
{
NSString *forExample;
}
- (void) set:(NSString *)one another:(NSString *)another;
- (void)print;
#end
Implementation:
#import "SomeClass.h"
#implementation SomeClass
NSString *anotherExample;
- (void) set:(NSString *)one another:(NSString *)another
{
forExample = one;
anotherExample = another;
}
- (void)print{
NSLog(#"One = %#, another = %#", forExample, anotherExample);
}
#end
Test:
- (void)testClass {
SomeClass * s1 = [SomeClass new];
[s1 set:#"one one" another:#"one another"];
SomeClass *s2 = [SomeClass new];
[s2 set:#"two one" another:#"two another"];
[s1 print];
[s2 print];
}
And the output is,
One = one one, another = two another
One = two one, another = two another
Use a code snippet to tell the difference between a member variable and a global variable:
#implementation MyClass {
// It is an ivar, or called member variable
// Can NOT be initialized when defined.
// Can be accessed with `self->_i`
int _i;
}
- (instancetype)init {
if (self = [super init]) {
_i = 2; // should be initialized before being used.
}
return self;
}
int i = 9; // Global variable, and can be initialized when defined.
- (void)myFun {
NSLog(#"%i, %i", self->_i, i);
}
#end
// Another file
extern int i;
NSLog(#"%i", i);
Just to be clear, never ever ever declare an IBOutlet as a global var (in the implementation) if you are using it for localized nibs/xibs.
I spent a few hours figuring why the outlet is connectable only in one of the localized nibs at any given time.
Thanks for this question and the answers!

%d doesn't show integer properly

As I try to write
NSLog(#"%d", myObject.myId);
where myId is int, console gives some hight number like 70614496. And when I use #"%#", I get exception -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x466c910.
Why is it so?
Here's definition of myObject:
#interface myObject : NSObject {
int myId;
NSString *title;
}
#property(nonatomic) int myId;
#property(nonatomic, retain) NSString *title;
#end
#implementation myObject
#synthesize myId, title;
- (void)dealloc {
[title release];
[super dealloc];
}
#end
Carl's doing a good job of trying to get your code to compile. Just another word on the %# format specifier, since your question seems to imply some confusion.
When you use %# in an NSLog format, you're actually sending the argument a description message, and printing the resulting string. If myId is an int and not an instance of NSObject, it doesn't respond to the description message. Use %d for int values and %# for NSNumber instances.
Here's an example showing that it should work the way you first tried it, if your class/object/instance variable are all set up correctly:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
{
int myId;
}
#property int myId;
#end
#implementation MyClass
#synthesize myId;
#end
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MyClass *myObject = [[MyClass alloc] init];
myObject.myId = 5;
NSLog(#"%d", myObject.myId);
[myObject release];
[pool drain];
return 0;
}
Your code shows you doing the equivalent of this line:
NSLog(#"%d", MyClass.myId);
Which doesn't even compile, giving the error:
foundation.m:21: error: accessing unknown 'myId' class method
Given that second error message, I think the %d is working fine, but somewhere else you’re assigning a CFNumber or NSNumber to the myID property when you should be assigning an integer.
It looks like your instance of myObject was autoreleased at some time and is no longer actually valid. That is why you see the strange NSNumber issue when you try to dereference it as an object. When you just ask for an integer, you won't get any kind of error, it will just display the pointer's address coerced into an integer.
To see when your myObject gets dealloced, try adding something like this to the dealloc method in your class:
- (void)dealloc
{
NSLog(#"dealloc called on %#", self);
[title release];
[super dealloc];
}
I bet you will find this logging a dealloc before you see the log for your myObject.myID.
I would try simply changing this:
#property(nonatomic) int myId;
to this:
#property(nonatomic, assign) int myId;
And let me know your result, I suspect that obj-c is doing something funky when assigning an old int to the new int?
Check out the String Format Specifiers to see how to format NSLog statements. It's easy to get lazy with NSLog because objects have a built-in -description method that returns a formatted string. For scaler values, you have to use the proper formatter.
Because precision changes as you move from hardware to hardware, it's better to get in the habit of using object conversions to log values. In this case:
NSLog(#"%#", [[NSNumber numberFromInt:myObject.myId] stringValue]);
This will print correctly always.
Edit#1: I apologize. I was sleep deprived when I wrote the above. What I actually intended was to warn against using a simple int versus NSInteger as well as printing with NSNumber numberWithInteger:.
Consider the following run on 64-bit hardware.
int x=pow(2,63);
NSLog(#"x=%d",x); //prints x=2147483647
NSInteger n=pow(2,63);
NSLog(#"n=%d",n); // prints n=-1
NSLog(#"n=%#",[[NSNumber numberWithInteger:n] stringValue]); // prints n=9223372036854775807
In the old days of 8-bit systems, you ran into problems with problems with using 8-bit 'int' all the time. Running a for-loop with more than 256 iterations required a long. With a 32-bit int you won't see those kinds of issues and will never develop the habit of tracking the size of your intvariables.
This can lead to pernicious bugs that are nearly impossible to track down because they only occur with very specific and rare values in the data.
Writing for the iPhone (or other future mobiles/platforms) means writing on potentially highly variable hardware just like we had to do in the old days. It's best to acquire the habit early of using system and API specific definitions.
Edit#2:
where myId is int, console gives some
hight number like 70614496.
(1) If it prints a different number each time you run, then you're probably assigning a pointer to the int when you set it. The NSLog is correctly printing the value of the pointer as an int.
(2) if it prints the same number each time, the you probably have an overflow issue like in my first edit above.
In either case, you need to look at code where you assign the value to the id property and not where you print it.