views:

1695

answers:

2

I was wondering if there is any sample code out there for objective-C for implementing a NSMutableArray of type struct. Inside, I need there to be 2 mutable arrays (via NSMutableArray also) declared in the struct. All the code samples in my book show me how to make an array of defined size via C array syntax (with the brackets), but I don't know how to get one going with NSMutableArray. Has anyone else done this before? Here's my code so far...It compiles fine I have defined the size of the arrays (2 and 5 are used in my code below as an example, but I need to set it so I can have them mutable. I can work with simple structs when they just have some of the "easier-to-understand" data types like int, double, short, long, BOOL (you get the idea). When it gets into pointers though, this is where I become lost (I can use pointers fine, but knowing how to put them in a struct is the difficult part). Once the code is working with NSMutableArray's, would I put "network" in the interface as a pointer to type "Network"? I tried this before, but I got errors. In the end, I basically want to be able to write

network.input[2].list[1].value = 5.0;

on an arbitrarily defined array of type "Network". Could anyone offer suggestion or links to information about making a NSMutableArray of type "Network" which includes a struct of two NSMutableArray's? Thanks for any help!

SomeFile.h

#import <Foundation/Foundation.h>

struct lists{
    double value;
};

// supporting structs
struct inputs{
    struct lists list[2];
};

struct Network {
    struct inputs input[5];
    struct lists output[5];
}

@interface SomeFile : NSObject {

}

@end

SomeFile.m

#import "SomeFile.h"
@implementation SomeFile
@end
+1  A: 
Quinn Taylor
+1  A: 

This is not be a complete answer; I’m not sure what you mean by not knowing how to put pointers in structs. I’m going to proceed by assuming you want to model an network of multiple inputs and outputs with a dynamic number of both.

You have a few choices here:

  1. Use value objects instead of structs to store your values:

    [[[network inputs] objectAtIndex:2] replaceObjectAtIndex:1 withObject:[NSNumber numberWithDouble:5.0]];
    
  2. Model your Network with an object:

    @interface Network : NSObject {
        // ivars
    }
    
    
    - (void) setInput:(double)value atIndex:(NSInteger)valueIndex ofInputAtIndex:(NSInteger)inputIndex;
    - (double) outputAtIndex:(NSInteger)index;
    @end
    
  3. Just use structs like you’re already doing; if you need to change the size up-front, use your friend malloc:

    struct Network_value {
      double value;
    }
    
    
    struct Network {
        struct Network_value **inputs;
        struct Network_value *outputs;
    };
    
    
    void Network_alloc(Network *n, unsigned inputs, unsigned input_values, unsigned outputs) {
        n->outputs = calloc(sizeof(Network_value), outputs);
        n->inputs = calloc(sizeof(Network_value *), inputs);
        while (inputs --> 0) {
            n->inputs[inputs] = calloc(sizeof(Network_value), input_values);
        }
    }
    
    
    void Network_free(Network *n, unsigned inputs) {
        free(n->outputs);
        while (inputs --> 0) {
            free(n->inputs[inputs]);
        }
        free(n->inputs);
    }
    
    
    Network network;
    Network_alloc(&network, 5, 2, 5);
    
    
    network.inputs[2][1].value = 5.0;
    
    
    Network_free(&network, 2);
    
  4. Combine ideas 2 and 3 by presenting a Network object but internally store the values with structs. This is probably a good idea if the number of inputs and outputs is very large.

Ben Stiglitz
I strongly recommend designing for garbage collection as well. Instead of malloc and calloc, it's good to investigate NSAllocateCollectable and NSMakeCollectable.
Quinn Taylor