Releasing NSMutableArray not affecting the count of elements in the array - objective-c

Could someone explain to me the following result?
//generate an array with 4 objects
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:2],
[NSNumber numberWithInt:3],
[NSNumber numberWithInt:4],
nil];
//release the array
[array release];
//get a count of the number of elements in the array
int count = [array count]; <--- count returns 4
Should my count not be zero? Does 'release' not remove all elements from the array?

The value of count is undefined, because after the last release accessing properties of the array is illegal: essentially, you are accessing a dangling pointer.
If you would like to clear out the array without invalidating it, use removeAllObjects method.

Related

NSMutableArray keep objects at indexSet

I am on Xcode 8.2, OSX not iOS, Objective-C
I have an NSMutableArray and an NSIndexSet. I want to remove ALL items of the array EXCEPT those at the NSIndexSet. So basically something like
[array keepObjectsAtIndexes:indexSet]; // just to carify i know this doesnt exist
What's the best way to do this? Can i somehow 'reverse' the index set?
You can construct an inverse of a given NSIndexSet by constructing an index set that has all indexes in range 0..arrayCount-1, inclusive, and then removing the indexes in your indexSet from it:
NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet initWithIndexesInRange:NSMakeRange(0, array.count)];
[indexesToRemove removeIndexes:indexesToKeep];
[array removeObjectsAtIndexes:indexesToRemove];
You can do this even without creating unnecessary arrays:
// Initial array
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:#[#"one", #"two", #"three", #"four", #"five"]];
// Indices we want to keep
NSIndexSet* indexSet = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(1, 3)];
// Preparing reversed index set
NSMutableIndexSet *indexSetToRemove = [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, [array count])];
[indexSetToRemove removeIndexes:indexSet];
// Removing objects from that set
[array removeObjectsAtIndexes:indexSetToRemove];
The output will be:
2017-05-11 20:10:22.317 Untitled 15[46504:32887351] (
two,
three,
four
)
Cheers
You could get the objects with objectsAtIndexes and replace the entire objects with the result.
NSArray *temp = [array objectsAtIndexes:indexSet];
[array replaceObjectsInRange:NSMakeRange(0, array.count) withObjectsFromArray: temp];

Convert NSarray to twodimensional array

I have a an one dimensional array which contains a vary numbers of object (depending on the userinput)
The NSArray is called homePlayersArray. This could example contain 2, 3, 5, 6, 4
The thing is i want to convert this to a two dimensional array where example.
{2,0}, {3,}, {5,0}, {6,0},{4,0}
the first value in the object will me by NSarray (called homepPlayersArray) and the second value will be 0.
What is the best way to obtain this?
//Your original array
NSArray *homePlayersArray = [[NSArray alloc] initWithObjects:
[NSNumber numberWithInt:2],
[NSNumber numberWithInt:3],
[NSNumber numberWithInt:5],
[NSNumber numberWithInt:6],
[NSNumber numberWithInt:4],nil];
//For your 2D array
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithCapacity:[homePlayersArray count]];
//populate as required
for(int i=0;i<[homePlayersArray count];i++){
NSArray *tempArray = [[NSArray alloc] initWithObjects:[homePlayersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
[secondArray addObject:tempArray];
}
//print out some results to show it worked
NSLog(#"%#%#",#"secondArray first object value 0: ",[[secondArray objectAtIndex:0] objectAtIndex:0] );
NSLog(#"%#%#",#"secondArray first object value 1: ",[[secondArray objectAtIndex:0] objectAtIndex:1] );
NSLog(#"%#%#",#"secondArray second object value 0: ",[[secondArray objectAtIndex:1] objectAtIndex:0] );
NSLog(#"%#%#",#"secondArray second object value 1: ",[[secondArray objectAtIndex:1] objectAtIndex:1] );

obj-c fetching strings from array

i'm new to obj-c (this is my first day class eheh) and i'm trying to change a label with a random string from a multidimensional array. plus, every time the button is hitten you switch the array. i know it's a bit odd eheh… this is the IBAction:
UIButton *button = (UIButton *)sender;
NSMutableArray *firstArray = [NSMutableArray array];
[firstArray addObject:#"foo"];
NSMutableArray *secondArray = [NSMutableArray array];
[secondArray addObject:#"bar"];
NSMutableArray *frasi = [NSMutableArray array];
[frasi addObject:firstArray];
[frasi addObject:secondArray];
NSMutableArray *array = [NSMutableArray arrayWithObjects:[frasi objectAtIndex:[button isSelected]], nil];
NSString *q = [array objectAtIndex: (arc4random()% [array count] )];
NSString *lab = [NSString stringWithFormat:#"%#", q];
self.label.text = lab;
all works, but the new label is
( "foo" )
instead of just foo (without quotes)... probably i mess in the last block of code...
ty
So, you create 2 mutable arrays, then add them to a new mutable array frasi. Then you get one of those two arrays and use it as the single element (because you use arrayWithObjects: instead of arrayWithArray:) of a new array array.
So array is an array that contains a single array element (instead of an array of strings as you may believe).
When you get an object from array, it's always the same single object that was used to initialize it: either firstArray or secondArray.
So you get an array of strings where you expect a string. When using stringWithFormat:, the specifier %# is replaced with the string description of that object.
A string returns itself as its own description. But the description of an array is the list of all its elements separated with commas and surrounded by parenthesis, which is why you get ( "foo" ).
So instead or creating unneeded arrays, you may just replace all the 8th last lines with this:
NSArray *array = [button isSelected] ? secondArray : firstArray;
self.label.text = [array objectAtIndex:arc4_uniform([array count])];
Actually u have array within array
Replace this line with yours:
NSString *q = [[array objectAtIndex: (arc4random()% [array count] )] objectAtIndex:0];

Weird behaviour of NSMutableDictionary

Take a look at this piece of code
- (NSMutableDictionary *)getUsersFromServer
{
//here we're getting list of users from the server
NSMutableDictionary * users = [[[NSMutableDictionary alloc] init] autorelease];
userresults = [[NSMutableArray alloc] init];
//all this will be replaced with users taken from the server. it's needed just for testing
for (int i = 0;i < 19;i++)
{
int wins = i ; float f_wins = (float)wins;
int losses = i * 2 ; float f_losses = (float)losses;
int withdr = i * 3 ; float f_withdr = (float)withdr;
float win_per = f_wins / ((f_wins + f_losses + f_withdr) / 100.0);
[userresults setArray:[NSMutableArray arrayWithObjects:[NSNumber numberWithInt:wins],
[NSNumber numberWithInt:losses],
[NSNumber numberWithInt:withdr],
[NSNumber numberWithFloat:win_per],
nil]];
[users setObject:userresults forKey:[NSString stringWithFormat:#"user number %i",i]];
}
[userresults release];
return users;
}
in each loop iteration i fill array with numbers and set it as value into NSMutableDictionary. As a key for each array serves formatted string which is unique by number of iteration counter. So... the problem is - the dictionary is always filled with SAME arrays for DIFFERENT keys. There are 19 arrays in the dictionary and ALL THEY ARE LAST ONES!!!! That is from the last iteration. And each one has different key!!! How could it happen??? What's going on???
userresults points to the same object, and you're modifying that same array with the setArray: method. Create a new array in each loop iteration instead:
NSArray *userData = [NSArray arrayWithObjects:[NSNumber numberWithInt:wins],
[NSNumber numberWithInt:losses],
[NSNumber numberWithInt:withdr],
[NSNumber numberWithFloat:win_per],
nil];
[users setObject:userData forKey:[NSString stringWithFormat:#"user number %i",i]];
userresults is declared outside the loop unnecessarily. You can forego mutable arrays here and just create a new NSArray with each iteration. Your problem stems from reusing the array declared outside the loop and putting new values in each time. Try this:
[users setObject: [NSArray arrayWithObjects:[NSNumber numberWithInt:wins], [NSNumber numberWithInt:losses], [NSNumber numberWithInt:withdr], [NSNumber numberWithFloat:win_per], nil];
[users setObject:userData forKey:[NSString stringWithFormat:#"user number %i",i]]
forKey:[NSString stringWithFormat:#"user number %i",i]];;

Objective-c - Sort some Numbers stored is variables

hello
I want to sort(ascending) some numbers stored in different variables(like int a=50,int b=60, etc..)!
How can i do that?
Thanks for any help!
You need to store the numbers in an NSArray, packaged in NSNumbers. Then you can do normal array sorting:
NSArray *array = [NSArray arrayWithObjects:
[NSNumber numberWithInt:a],
[NSNumber numberWithInt:b],
nil
];
NSArray *sorted = [array sortedArrayUsingSelector:#selector(compare:)];
Put them into NSArray or NSMutableArray and sort the array