简体   繁体   中英

NSArray to NSMutableArray as random stack

Just a conceptual description first:

I am reading input from a text file (a list of words) and putting these words into an NSArray using componentsSeparatedByString method. This works.

But I wanted to select the words randomly and then delete them from the array so as to ensure a different word each time. Of course, you cannot change the NSArray contents. So...

I copied the contents of the NSArray into an NSMutableArray and use IT for the selection source. This also works - 269 objects in each array.

To return a word from the NSMutableArray I use the following code: note- the arrays are declared globally as

arrMutTextWords = [[NSMutableArray alloc] init];  //stack for words 
arrTextWords = [[NSArray alloc] init];  //permanent store for words


-(NSString*) getaTextWord
{

// if the mutable text word array is empty refill

if ([arrMutTextWords count] == 0){

    for (int i = 0 ; i < [arrTextWords count]; i++) 
        [arrMutTextWords addObject:[arrTextWords objectAtIndex:i]];
}

int i = random() % [arrMutTextWords count];
NSString* ptrWord = [arrMutTextWords objectAtIndex:i];
[arrMutTextWords removeObjectAtIndex:i];
return ptrWord;

}

The program crashes during a call to the method above - here is the calling code: arrTmp is declared globally arrTmp = [[NSArray alloc] init]; //tmp store for words

for (int i = 0 ; i < 4; i++) {
    tmpWord = [self getaTextWord];
    [arrTmp addObject:tmpWord];
    [arrTmp addObject:tmpWord];
}

I'm thinking that somehow deleting strings from arrMutTextWords is invalidating the NSArray - but I can't think how this would occur.

One possible source for problems is your fetching AND removing the NSString object from your list. Removing it releases that NSString instance therefore devalidating your reference.

To be shure to retain a reference you should use this code sequence instead:

NSString * ptrWord = [[[arrMutTextWords objectAtIndex:i] retain] autorelease];
[arrMutTextWords removeObjectAtIndex:i];
return ptrWord;

By the way: You should use

NSMutableArray *mutableArray = [NSMutableArray arrayWithArray: array];

instead of copying all values by hand. While i do not know the implementation of NSMutableArray , i know from times long ago (NeXTstep), that there are several possible optimizations that may speed up basic NSArray operations.

And finally copying this way is much more concise.

Just ran this through XCode and got random words returned, however I skipped the whole for loop and used addObjectsFromArray from NSMutableArray .

NSArray *randomArray = [[NSArray alloc] initWithObjects:@"Paul", @"George", @"John", nil];
NSMutableArray *muteArray = [[NSMutableArray alloc] init];
[muteArray addObjectsFromArray:randomArray];

int i = random() % [muteArray count];
NSString* ptrWord = [muteArray objectAtIndex:i];
[muteArray removeObjectAtIndex:i];
NSLog(@"ptrWord %@", ptrWord); //gave me a different name each time I ran the function.

Hope this clears some things up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM