Getting a random object from an array, then remove it from array. iphone
I am having a problem with arrays, I want an object to be picked randomly from the array, and then remove it and remove other objects that are specified in 开发者_JS百科the "if" statement.
What I did..
in the .h
NSMutableArray *squares;
int s;
NSString *randomN;
Next, in the .m
Create a new array:
-(void) array{
squares = [[NSMutableArray alloc] arrayWithObjects: @"a", @"b", @"c", nil];
}
and then choose a random object, if properties of the "if" met, remove the object from the array, do the while loop again.
-(void) start{
s=5;
while (s > 0){
//I even tried it without the next line..
randomN = nil;
//Also tried the next line without ' % [squares count'
randomN = [squares objectAtIndex:arc4random() % [squares count]];
if (randomN == @"a"){
[squares removeObject: @"a"];
[squares removeObject: @"b"];
s = s - 1;
}
if (randomN == @"b"){
[squares removeObject: @"b"];
[squares removeObject: @"c"];
s = s - 1;
}
if (randomN == @"c"){
[squares removeObject: @"c"];
s = s - 1;
}
else {
s=0;
}
}
}
When I run the app, the app stops and quits as soon as the loop starts.
Can you please help me?
Their are a few issues that are probably tripping you up:
You're initializing an already allocated array with a convenience constructor, you should pick one of the alloc
/init
pair or the convenience constructor by itself:
[[NSMutableArray alloc] initWithObjects:...]
or:
[NSMutableArray arrayWithObjects:...]
Your remove lines are attempting to remove string literals. While your array contains string instances that contain the same values as the strings you're trying to remove, they're not the same exact instances of the string. You need to use [stringVar isEqualToString:otherStringVar]
to compare the values instead of their references:
if ([randomN isEqualToString:@"a"])
instead of:
if (randomN == @"a")
Also, your else
statement will fire every time for similar reasons as the second problem. Even if you use the correct string comparisons, your logic is probably off if you're trying to only execute one of those 4 blocks of code. To accomplish that, each of the if
s after the first needs an else
, like so:
if (/* test 1 */) {
}
else if (/* test 2 */) {
}
else if (/* test 3 */) {
}
else {
// chained else's make only one block able to execute
}
instead of:
if (/* test 1 */) {
}
if (/* test 2 */) {
}
if (/* test 3 */) {
}
else {
// this else only applies to the LAST if!
}
I think the problem is that you should be using initWithObjects
when creating the array (rather than arrayWithObjects
).
You should always use an init*
method after using alloc
to create a new object.
The arrayWith*
methods are 'convenience constructors' that autorelease
the returned object. By the time you come to using it, the array has probably been freed.
In objective-c, you can't compare strings using ==
, you have to use the isEqual:
method. The @"string"
notation produces a pointer to a string defined elsewhere in memory, and these can be different, even though the data they point to is the same.
So, instead of
if (randomN == @"a"){
try
if ([randomN isEqual:@"a"]){
As Alex said,
squares = [[NSMutableArray alloc] arrayWithObjects: @"a", @"b", @"c", nil];
This line should be
squares = [[NSMutableArray alloc] initWithObjects: @"a", @"b", @"c", nil];
or
squares = [[NSMutableArray arrayWithObjects: @"a", @"b", @"c", nil] retain];
Also,
randomN = [squares objectAtIndex:arc4random() % [squares count]];
If squares is empty, EXC_ARITHMETIC exception (Division by Zero) occurs on this line.
精彩评论