I ran across this presentation when searching Google for TDD principles
http://qualitycoding.org/files/BowlingGame-ObjectiveC.pdf
There's something I'm not familiar with in it. There's a declaration like this:
NSUInteger _rolls[21];
NSUInteger _currentRoll;
From following the code I've found that _rolls is an array containing several uints. But I have never seen this. Is this a part of C?
I would be more familiar with
NSArray *rolls;
NSUInteger aRoll = rolls[index];
Is the [21] describing the count, or the max limit for this array?
NSUInteger _rolls[21]; is declaring a C array of NSUInteger types with a size of 21, not an NSArray.
Think about how you would declare an array in C:
type arrayName [ arraySize ];
With ints:
int rolls[5] = {1, 2, 3, 4, 5};
It works the same way.
The number in the brackets is the size of the array, the maximum number of values it can hold.
Actually, an NSArray cannot contain NSUInteger, you can only put objects in an Objective-C array.
If you want to store NSUIntegers in an array, you'll have to wrap them first:
NSArray *rolls = [NSArray arrayWithObject: #(17)];
NSUInteger aRoll = rolls[0].unsignedIntegerValue;
Or, you can use a C array like the one you saw in the PDF...
Related
Is there an efficient way to reorder NSMutableArray by changing its starting index? Example: if my array is [A,B,C,D,E], I would like to set 3rd element as starting element, and thus create the array [C,D,E,A,B].
I am doing it by slicing the array into two separate array, and then concatenating them. Is there a more efficient or clean way to do this?
Edit: the following is my current code
NSArray myArray = [self getMyArray]; // [A,B,C,D]
int startingIndex = 2;
NSArray *subArray1 = [myArray subarrayWithRange:NSMakeRange(_startingIndex, [myArray count] - _startingIndex + 1)]; // [C,D]
NSArray *subArray2 = [myArray subarrayWithRange:NSMakeRange(0, _startingIndex - 1)]; //[A,B]
NSMutableArray *reorderedArray = [NSMutableArray arrayWithArray:subArray1];
[reorderedArray addObjectsFromArray: subArray2]; //[C,D,A,B]
The most economical way of rotating NSMutableArray in terms of additional memory is the double-reversion algorithm described in this Q&A, because it does not require any additional storage. The idea is to reverse the entire array, and then reverse the two ranges separately.
In your example the array would be reversed, like this
E D C B A
then the first three elements would be reversed
C D E B A
and finally the tail of the array would be reversed:
C D E A B
Make a helper function for reversing a range, and call it three times:
reverseInPlace(myArray, 0, myArray.count-1);
reverseInPlace(myArray, 0, _startingIndex);
reverseInPlace(myArray, _startingIndex+1, myArray.count-1);
One way to implement reverseInPlace is as follows:
static void reverseInPlace(NSMutableArray *a, int f, int b) {
while (f < b) {
[a exchangeObjectAtIndex:f++ withObjectAtIndex:b--];
}
}
No, NSMutableArray is not documented to behave as a circular buffer (ring buffer), nor does it have operations you'd expect to have in one. Some potentially useful resources for solving this with a data structure where rotations have an O(1) cost:
Answer to a related Objective-C question about ring buffers, linking to CHDataStructures available also as a pod if you are so inclined.
Boost.Circular: a C++ circular buffer which you could wrap into some Objective-C++ for your purposes.
If all you need is to rotate a fixed, predictable length buffer, a circular buffer is a simple data structure to implement yourself. Apple's CoreAudio utility classes also include a general purpose ring buffer (CARingBuffer) you may find useful as a reference for your implementation.
If an in-place O(N) solution is sufficient for your needs, the other answer is a better choice than the varyingly complicated things I'm proposing above.
More efficient and cleaner:
NSRange range = NSMakeRange(0, startingIndex - 1);
NSArray *subArray = [array subarrayWithRange:range];
[array removeObjectsInRange:range];
[array addObjectsFromArray:subArray];
I am using objective c to create a struct holding a variable length array. I know you can create an array of length n like so:
double array[n];
And i also believe in c++ you can declare:
vector<double> array;
where you do not have to declare the array length. Is there any way to do something similar in objective c? I am using ARC.
Thanks in advance, Ben
You just need to create an NSMutableArray like-
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:....];// Add as many object as you want.
You just need to take care of one thing while creating variable length array, don't add nil as object, as nil is just to signify the end of the variable-length argument list.
EDIT -
Might be following will help you -
In this way you can define objective c data types in struct-
typedef struct{
int numInputs;
__unsafe_unretained NSMutableArray *array;
} Pin;
Is there any quick way I can get the number of strings within a NSString array?
NSString *s[2]={#"1", #"2"}
I want to retrieve the length of 2 from this. I there something like (s.size)
I know there is the -length method but that is for a string not a string array.
I am new to Xcode please be gentle.
Use NSArray
NSArray *stringArray = [NSArray arrayWithObjects:#"1", #"2", nil];
NSLog(#"count = %d", [stringArray count]);
Yes, there is a way. Note that this works only if the array is not created dynamically using malloc.
NSString *array[2] = {#"1", #"2"}
//size of the memory needed for the array divided by the size of one element.
NSUInteger numElements = (NSUInteger) (sizeof(array) / sizeof(NSString*));
This type of array is typical for C, and since Obj-C is C's superset, it's legal to use it. You only have to be extra cautious.
sizeof(s)/sizeof([NSString string]);
Tried to search for _countf in objective-c but it seems not existing, so assuming that sizeof and typeof operators works properly and you pass valid c array, then the following may work.
#define _countof( _obj_ ) ( sizeof(_obj_) / (sizeof( typeof( _obj_[0] ))) )
NSString *s[2]={#"1", #"2"} ;
NSInteger iCount = _countof( s ) ;
a.H:
-(NSArray *) returnarray:(int) aa
{
unsigned char arry[1000]={"aa","vv","cc","cc","dd"......};
NSArray *tmpary=arry;
return tmpary;
}
a.c:
#include "a.H"
main (){
// how do I call returnarray function to get that array in main class
}
I need that array in main and I need to retain that array function in separate class.
Can someone please provide a code example to do this?
These lines:
unsigned char arry[1000]={"aa", "vv", "cc", "cc", "dd", ...};
NSArray *tmpary=arry;
Should instead be:
unsigned char arry[1000]={"aa", "vv", "cc", "cc", "dd", ...};
NSMutableArray * tmpary = [[NSMutableArray alloc] initWithCapacity: 1000];
for (i = 0; i < 1000; i++)
{
[tmpary addObject: [NSString stringWithCString: arry[i] encoding:NSASCIIStringEncoding]];
}
This is because a C-style array (that is, int arr[10]; for example) are not the same as actual NSArray objects, which are declared as above.
In fact, one has no idea what an NSArray actually is, other than what the methods available to you are, as defined in the documentation. This is in contrast to the C-style array, which you are guaranteed is just a contiguous chunk of memory just for you, big enough to hold the number of elements you requested.
C-style arrays are not NSArray's so your assignment of arry (the definition of which has some typos, at least the unsighned part) is not valid. In addition, you call arry an array of char, but you assign it an array of null-terminated strings.
In general you need to loop and add all the elements of the C-style array to the NSArray.
I'm not sure why you must do it in main. If you want a global you can do it by declaring a global in another file. That said, you CANNOT assign a plain C data array to an objective C NSArray, which is different in nature entirely.
I have an NSArray arr. It has a bunch of NSNumber objects. I'm trying to calculate statistics analysis on the array using GNU's GSL. GSL takes parameters as C-style arrays.
Is there any mechanism that can, for example, run 'intValue' on all of the objects in a NSArray object, and convert the results that to a C-style array?
I don't really want to copy the contents of the NSArray to a C-style array, as it's a waste of space and cycles, so I'm looking for an alternative.
The mechanism you're describing — run intValue on all the objects in the NSArray and give a C-style array — seems to be exactly the same thing you describe as "a waste of space and cycles." It's also the only real way to do this if you need a C-style array of ints. Best approach I can think of:
int *c_array = malloc(sizeof(int) * [yourArray count]);
[yourArray enumerateObjectsWithOptions:NSEnumerationConcurrent
usingBlock:^(id number, NSUInteger index, BOOL *unused) {
c_array[index] = [number intValue];
}];
Try this:
id *numArray = calloc(sizeof(id), yourArray.count);
[yourArray getObjects: numArray range: NSMakeRange(0, yourArray.count)];
That gives you a C-array of NSNumbers. An alternative that gives you ints:
int *numArray = calloc(sizeof(int), yourArray.count);
for (int i = 0; i< yourArray.count; i++)
numArray[i] = [[yourArray objectAtIndex: i] intValue];
There is no way to tell yourArray to return a C-array of ints directly. NSArray has no concept of the contents it has, except that they are ids, and must be retained and released at the right times. It can at most return a C-array of ids, as in my first example.
You could probably write your own simple array class that contains ints (or floats or doubles, etc.) directly, in an internal C array, but there is no stock class for this.