Passing and recieving multi-dimensional primitive (int) arrays in objective-c - objective-c

I have two objective c methods. One needs to return an int[][] and the other which needs to take int[][] as a parameter. I was originally using an NSMutableArray with NSMutableArrays as values however I was told to redo it like this in order to be compatible with some current code. I can't figure out how to make this work. I'm not sure I'm even googling the right thing. Anyway here is what I have now.
+(int [][consantValue]) getCoefficients
{
int coefficiennts [constantValue2][constantValue1] = { {0,1,2}, {3,4,5}, {6,7,8} };
return coefficients;
}
At the return statement I get the Error "Array initilizer must be an initializer list'
I also have to take the int[][] and rebuild it into an NSMutableArray of NSMutableArrays in another method but I'm hoping if someone can give me a hint on the first part I can work the second part out myself although if anyone has any advice on that I would appreciate it as well. Thanks.

The easy way to do this for fixed size array(s) is to use a struct for storage:
typedef struct {
int at[constantValue2][constantValue1];
} t_mon_coefficients;
And then you'd declare the method which returns by value:
+ (t_mon_coefficients)coefficients;
And passes by value as a parameter:
- (void)setCoefficients:(const t_mon_coefficients)pCoefficients;
If the struct is large, you should pass by reference:
// you'd use this like:
// t_mon_coefficients coef;
// [SomeClass getCoefficients:&coef];
+ (void)getCoefficients:(t_mon_coefficients* const)pOutCoefficients;
- (void)setCoefficients:(const t_mon_coefficients*)pCoefficients;
But there are multiple ways one could accomplish this.

Related

How to convert valueForKeyPath in swift

My old function in objective c is
+ (NSUInteger)getNumberOfDistinctUsers:(NSArray *)users {
NSArray* usersAfterPredicate = [users valueForKeyPath:#"#distinctUnionOfObjects.userName"];
return [usersAfterPredicate count]; }
How do I convert this in swift, I was trying to something like this but its crashing "Could not cast value of type 'Swift.Array'to 'Swift.AnyObject'"
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
var retval : Int = 0
if let usersAfterPredicate = (users as! AnyObject).valueForKeyPath("#distinctUnionOfObjects.userName") {
retval = usersAfterPredicate.count
}
return retval
}
Can I solve this problem using filter, map or Reduce? I am just trying to find out distint users in users array using the property username.
Edit* brute force way
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
var retvalSet : Set<String> = []
for user in users {
retvalSet.insert(user.userName)
}
return retvalSet.count
}
As you suspect, you can simplify the code with a simple map:
static func getNumberOfDistinctUsers(users: [ICEPKReferenceDataUser]) -> Int {
return Set(users.lazy.map{$0.userName}).count
}
This uses the fact that you can initialize a Set using any other sequence.
I added lazy in there to avoid creating an extra copy of the array. It'll work with or without, but I expect it to be much more memory efficient this way. Array.map creates another Array. array.lazy.map return a lazy collection that computes values as requested.
That said, I don't know that my approach is dramatically better than your "brute-force" way. It's not obvious which is easer to read or maintain. I have a fondness for the map approach, but it can be a tradeoff (I had to know to add lazy for instance, or I could have allocated significant memory if this were a large array). Your code makes it very clear what's going on, so I don't think there's any problem that has to be solved there.
If you really wanted to use KVC, you'd need to convert your array to an NSArray, not an AnyObject, but I suspect that the above code is much faster, and is clearer and simpler, too, IMO.

How to Implement a Decision Table in Objective-C

I am a novice programmer, and I've just started reading about decision tables. I have read Chapter 18 in Code Complete and it was very enlightening. I looked around the web to try to find any kind of example of decision tables in Objective-C and I was unable to find any boilerplate or real world examples of how to implement this.
I am programming a game in Objective-C in my spare time, and I have been dealing with increasing complexity for the rules of the game. There are a handful of somewhat deeply nested if-else statements, as well as a few switch statements that already have 10 or more cases to deal with. I think it would be easier to work with decision tables, but I have no idea how to implement this in Objective-C for something non-trivial like the logic of a game.
For example, I need different methods to execute for different combinations of states. How would I implement a decision table in Objective-C that could take different combinations of states as keys, and run specific logic based on the combination of them?
Well I thought about decision tables in Objective-C some more and came up with a solution to implement a basic one. I will not post the entire code here, just the snippets that make the decision table work and their basic purpose. I posted this over at Code Review SE if you want to see the full code and some great suggestions for how to improve it. I'm posting this now because someone posted a comment requesting that I do so, but I will definitely end up improving this and integrating the suggestions from the review. Anyway, here is the code.
First before the initialization method I establish a number of NSString constants that will be used as the keys in an NSDictionary.
//Two options for the decision table, either access the dictionary directly with 0-x, the enum values, or make strings for their names
//the advantage of strings is that it is more extensible, and the position in the enum doesnt matter
NSString* const kEnemyMovementStateJustSpawned = #"enemyMovementStateJustSpawned";
NSString* const kEnemyMovementStateIdle = #"enemyMovementStateIdle";
NSString* const kEnemyMovementStateNeedsMoving = #"enemyMovementStateNeedsMoving";
NSString* const kEnemyMovementStateToFloor = #"enemyMovementStateToFloor";
NSString *const kEnemyMovementStateAtDestinationFloor = #"enemyMovementStateAtDestinationFloor";
NSString* const kEnemyMovementStateToFloorExit = #"enemyMovementStateToFloorExit";
NSString* const kEnemyMovementStateToAttackWalls = #"enemyMovementStateToAttackWalls";
NSString* const kEnemyMovementStateToAttackFloor = #"enemyMovementStateToAttackFloor";
NSString* const kEnemyMovementStateToAttackRoom = #"enemyMovementStateToAttackRoom";
Then I use these constants along with the names of methods in the class to build the NSDictionary:
-(void) setupDecisionTable {
//the string objects are the names of methods in the class
_decisionTable = #{kEnemyMovementStateJustSpawned: #"doEnemyJustSpawned",
kEnemyMovementStateIdle: #"doEnemyIdle",
kEnemyMovementStateNeedsMoving: #"doEnemyNeedsMoving",
kEnemyMovementStateToFloorExit: #"doFloorMovement",
kEnemyMovementStateToFloor: #"doVerticalMovement",
kEnemyMovementStateAtDestinationFloor: #"doEnemyAtDestinationFloor",
kEnemyMovementStateToAttackWalls: #"doFloorMovement",
kEnemyMovementStateToAttackFloor: #"doFloorMovement",
kEnemyMovementStateToAttackRoom: #"doFloorMovement"
};
}
Then every tick I call this method, which executes the method with the name of the object pulled from the dictionary:
-(void) doMovement {
//the selector is formed from a string inside the decision table dictionary
SEL methodToCallName = NSSelectorFromString([_decisionTable objectForKey:[self stringForState:self.state]]);
if (methodToCallName) {
IMP functionPointer = [self methodForSelector:methodToCallName];
void (*methodToCall)(id, SEL) = (void *)functionPointer;
methodToCall(self, methodToCallName);
}
}
-(NSString *) stringForState:(EnemyMovementState)state {
switch (state) {
case EnemyMovementStateJustSpawned:
return kEnemyMovementStateJustSpawned;
case EnemyMovementStateIdle:
return kEnemyMovementStateIdle;
case EnemyMovementStateNeedsMoving:
return kEnemyMovementStateNeedsMoving;
case EnemyMovementStateToFloor:
return kEnemyMovementStateToFloor;
case EnemyMovementStateAtDestinationFloor:
return kEnemyMovementStateAtDestinationFloor;
case EnemyMovementStateToFloorExit:
return kEnemyMovementStateToFloorExit;
case EnemyMovementStateToAttackWalls:
return kEnemyMovementStateToAttackWalls;
case EnemyMovementStateToAttackFloor:
return kEnemyMovementStateToAttackFloor;
case EnemyMovementStateToAttackRoom:
return kEnemyMovementStateToAttackRoom;
default:
return nil;
}
}
Finally here are a couple of the methods that execute, just for a complete example:
-(void) doEnemyIdle {
if ([self checkFloorsForJobs]) {
self.state = EnemyMovementStateNeedsMoving;
} else {
[self doIdleMovement];
}
}
-(void) doEnemyNeedsMoving {
[self calculateFloorExitPositionByFloor];
self.state = EnemyMovementStateToFloorExit;
}
This is a pretty simple implementation. Currently it can only deal with one input, and a better decision table would be able to evaluate multiple inputs and provide the proper output. I think it could be extended by having an intermediate method that took the state combined with other variables to choose the proper object from the dictionary.
After doing all this, I'm not sure that decision tables are worth the effort in Objective-C. I do not know if the code is easier to understand than a switch statement. In order to add new logic to the code, it has to be modified in more places than a switch statement would seem to require. I provide this code as an example, and it would be cool to see other versions of decision tables in Objective-C if anyone has one.

How can I do C pointer arithmetic in a C file which is part of an Xcode 4.3.3 Objective-C project for iPad?

I have what looks to me an innocent cycle which iterates on elements of an array whose type is unknown at compile time; my array is named mesh->vertices and is a pointer to void. Depending on the truth value of mesh->textured I need to consider the array differently. Incidentally, the code in the if and the else in the code segment below is similar, but I do need to distinguish two cases.
void TransformMesh(struct Mesh *mesh, struct Matrix4 *t)
{
for (int i = 0; i < mesh->nVertices; ++i)
{
if (mesh->textured)
{
struct TexturedVertex *ptr = ((struct TexturedVertex *)mesh->vertices) + i;
ptr[i].position = MatrixPointMultiply3(t, &ptr->position);
ptr[i].normal = MatrixPointMultiply3(t, &ptr->normal);
}
else
{
struct Vertex *ptr = ((struct Vertex *)mesh->vertices) + i;
ptr[i].position = MatrixPointMultiply3(t, &ptr->position);
ptr[i].normal = MatrixPointMultiply3(t, &ptr->normal);
}
}
}
I guess I created the project with the Automatic Reference Counting option, thinking that it would not have affected C code, but now I feel like I'm wrong (by the way, how can I check which option I chose?).
Well, it looks like this function is doing something wrong with another array, called mesh->triangles, probably freeing it. When I try to use the vector I get an EXC_BAD_ACCESS error:
glDrawElements(GL_TRIANGLES, mesh->nTriangles * 3, GL_UNSIGNED_INT, mesh->triangles);
It looks like iterating on the mesh->vertices elements, casting them and doing the pointer arithmetic, is corrupting the memory. I think my problem is ARC, so I tried to do what described here but with no luck.
EDIT:
The code above was wrong, as pointed out by Conrad Shultz; the following is correct:
ptr->position = MatrixPointMultiply3(t, &ptr->position);
ptr->normal = MatrixPointMultiply3(t, &ptr->normal);
I seriously doubt ARC has anything to do with this - ARC only manages Objective-C objects. (It doesn't even know how to handle Core Foundation types, which leads to the requirement for using the __bridge... keywords.)
I'm struggling to understand your code. Admittedly, I don't do a great deal of straight C programming, but I don't get what you're trying to do by adding i to ptr, which is presumably the pointer arithmetic of which you speak.
Are you trying to just access the ith struct TexturedVertex in mesh->vertices? If so, just use your ptr[i] construct as written.
It looks to me like you are doing arithmetic such that ptr ends up pointing to the ith struct TexturedVertex, then by accessing ptr[i] you are reading i elements past the ith struct TexturedVertex. If nVertices refers to the count of vertices (as would seem logical, given the name and C array conventions), you are then reading past the end of vertices, a classic buffer overflow error, which would unsurprisingly lead to EXC_BAD_ACCESS and all sorts of other fun errors.

How to avoid if else or switch case whe dealing with enums?

I have a member variable that tells units for a value I have measured like centimeters,kilometers,seconds,hours etc.
Now these are enums,
When I display a corresponding string, I have created a method that returns corresponding string for these enums.
Unlike Java, enums here cant have other properties associated with them.
So I have to explicitly do a if-else-if chain or a switch case to return the correct string.
I am new to Objective C. any good practice that I should be following in such scenarios ?
afaik Objective-C enums are just old-school C enums... so maybe you can use an integer value for them?
I guess if your enum values started at 0 and increased you could use some sort of array access:
const char *distanceUnitToString2(enum DistanceUnit unit)
{
const char *values[] = {
"cm",
"m",
"km"
};
// do some sanity checking here
// ...
return values[unit];
}
But this feels a little flaky to me. What if you have negative values, or you are using bitmask-style enum values like 1 << 8? You are going to end up using a very large array.
You also could use a switch and improve it a little with a macro. Something like this:
const char *distanceUnitToString(enum DistanceUnit unit)
{
#define CASE(UNIT, STRING) case (UNIT): return (STRING)
switch (unit) {
CASE(kCentimeters, "cm");
CASE(kMeters, "m");
CASE(kKiloMeters, "km");
default:
// should not get here
assert(0);
break;
}
#undef CASE
}
But you don't really save that much vs. not using the macro.
Martin James's comment is the right answer. And use a definition of the enum like:
enum units { cm = 0, m, km };
that way you can be sure that your enum translates to the correct index values.

indexOfObject does not match correctly

I've been stuck with this problem from a couple of days and I can't get myself out of it.
I've searched all over the net, but I couldn't find anything useful to solve my issue.
this is the scenario.
I've got an array of strings containing a bunch of ids fetched from a coredata sqlite db and
I'd like to know the index of a certain element into this array.
My first solution would have been as easy as using indexOfObject
-(NSInteger) getPageId:(NSString *)symbol_id {
NSInteger refId = [myIds indexOfObject:symbol_id];
// .. stuff ..
return refId;
}
now, I don't know why, but the returning value of the function is always NSNotFound.
If I print out the values via NSLog
NSLog(#"%#\n%#", myIds, symbol_id);
I can clearly see that the value I'm searching for figures out into the elements of the array.
I've even tried a dumbest solution, like probing the match via isEqual function into a for loop:
int idx = 0;
for(NSString *tok in myIds) {
if([tok isEqual:synmbol_id])
{
NSLog(#"yay, a match was encountered!!");
return idx;
}
idx++;
}
but the execution never gets into the NSLog.
I dunno where to knock my head.
hope that some of you already figured this out and could explain this to me.
thx in advance
k
Try printing all the elements on the array like this:
for(NSString *tok in myIds) {
NSLog(#"On the array [%#]", tok);
}
Maybe there is a TAB \t, an ENTER \n or something weird in your NSString preventing isEqual message to run as expected. Usually these characters are hard to find on a regular debugger. That's why I'am suggesting to enclose the string in [].