• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1386
  • Last Modified:

Access a primitive array of pointers in a class

I want to access the elements of an array of objects in a class. I can access elements of an array of intrinsic data types but not objects.The highly simplified code sample below explains. Is this possible? Don't want to use NSARRAY for the array of objects if possible. Could do custom accessors, but do not know how to accept the index into the array generated by a line like x=class.object[index] into the custom getter for instance. I realise I could code custom getter/setter such that this sort of thing would work x = [class objectAtIndex:index] and [class setObject:value atIndex:index] but I want to access them inline native C syntax style.

SingletonClass.h:----------------------

@class AnotherClass;

@interface SingletonClass : NSObject {

    int numbers[10];
    AnotherClass *objects[10];

}

@property (nonatomic,assign) int *numbers;
@property (nonatomic,assign) AnotherClass **objects;

- (int*)numbers;
- (AnotherClass**)objects;
+ (SingletonClass*)singletonClassInstance;

@end

SingletonClass.m:-------------------------

@implementation SingletonClass

- (int *)numbers {
      return numbers;
}

- (AnotherClass **)objects {
      return *objects; // this line gets a warning "Return from incompatible pointer type"
}

static SingletonClass *singletonClassInstance = nil;

+ (SingletonClass *)singletonClassInstance {
      
      @synchronized(self) {
            if(singletonClassInstance == nil) {
                  [[self alloc] init];
            }
      }
      
      return singletonClassInstance;
}

@end

MainClass.h:----------------------

#import "SingletonClass.h"
#import "AnotherClass.h"

@interface MainClass:NSObject {

    SingletonClass *sharedClass;

}

@end

MainClass.m:---------------------

#import "MainClass.h"

@implementation MinaClass

-(id)init {
    self = [super init];
    if (self != nil) {
        [self initialisation];
    }
    return self;
}

-(void) initialisation {

    sharedClass = [SingletonClass singletonClassInstance];
    sharedClass.objects[1] = [[AnotherClass alloc] initWithSomething:something]; // THIS FAILS gets terminating due to uncaught exception

}

-(void)anotherMethod {

    sharedClass.numbers[1] = 5; // THIS WORKS FINE
    sharedClass.objects[1].someAnotherClassProperty = value; // THIS FAILS if no initialisation of objects[1] with terminating due to uncaught exception (expected if objects not alloc'd)

}

@end
0
tiggr009
Asked:
tiggr009
  • 4
  • 3
1 Solution
 
pgnatyukCommented:
I'd say the problem is here:
@property (nonatomic,assign) AnotherClass **objects;

- (AnotherClass **)objects {
      return *objects;
}

I think it should objects and not *objects.

Can you just add a method

-(AnotherClass*) get : (int) index;

if you need to access to the elements of this array?
0
 
tiggr009Author Commented:
Thank you for your response. But that does not work either.

I tried changing "return *objects" to "return objects". The IDS did not warn about an incompatible pointer type any more, but the resulting executable still threw an uncaught exception when trying "sharedClass.objects[1] = [[AnotherClass alloc] initWithSomething:something];"

What the working "@property ... int* numbers" and "-(int*)number" combination does I believe is fudge access to primitive C array of ints in a way that was not intended. By me providing a pointer property to the int array, the GCC compiler can properly deal with statements like "int x=class.numbers[index]". However when I try to do the same with an array of pointers the resulting executable is dud. I just think that this fudge does not extend to an array of pointers.

My question was posted at 2:00 am my time so maybe I was a little vague about what I wanted and heavy on the details about what I had tried to do to accomplish it. So I will elaborate on things.

What I want is to have a singleton class as a shared resource pool. The resource pool contains an array of image objects (an image management class) that will shared by multiple instances of a game object (a logic filed class the utilised image objects from the resource pool). The game instantiates the game object multiple times with each instance referencing the same shared pool of image objects.

In the game object code I wish to programatically access the members of the image object array of the resource pool, and their properties, using dot notation C++ syntax and not Objective-C syntax.

David
 
0
 
tiggr009Author Commented:
ADDITIONAL COMMENT

Re-reading my response I need to explain more. In the singleton class I want an array of image classes. e.g. "Image *images[12];" and I want to I want to make that array a property of the class so that the members of the array are available outside the class. Accessible as "singeltonClass.images[index]".

Ideally if the statements "@property ...... *images[12];" and "@synthesize images" worked I would be happy. However my guess is that the @synthesize can't build setters and getters for arrays.

I could roll my own setters and getters for the array thus:

-(Image*)images:(int)index {
      return images[index];
}
-(void)setImages:(Image*)aValue atIndex:(int)index {
      images[index] = aValue;
}

But I cannot use these in dot notation syntax like "singletonClass.images[1] = aLoadedImage;" but I can use [singletonClass setImages:aLoadedImage atIndex:1];. My guess is the compiler cannot bind the dot notation code to the custom setters/getters.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
pgnatyukCommented:
I need to check. I was busy the whole day and only now get to my computer.
In our usual C++ we could write just the operator []. I do have such containers in my apps. I do not use singleton in your way. Once it was just a static member in one of the base GUI screen classes with an internal counter (like AddRef, Release) and now it is just a global variable - I have to say it is simple and fine way and it allow me to control the resources loaded or unloaded. Sorry, the question is not about it. I hope now I will check this array of pointers and will come back to you.
0
 
pgnatyukCommented:
Please check the attached code.
It is a simple Command Line Utility -> Foundation Tool project.
It was very fast and dirty, but it works - you can see something.array[i].x as you wanted.
And there is no warnings or compilation errors (of course, I was lazy to release the memory for the array - sorry).


#import <Foundation/Foundation.h>

@interface Dot: NSObject
{
	int x;
	int y;
}

@property int x, y;

@end;

@implementation Dot

@synthesize x, y;

@end

@interface Something : NSObject
{
	Dot** array;
}

@property (nonatomic, assign) Dot** array;

- (Something*) initWithCapacity : (int)n;

@end

@implementation Something

@synthesize array;

-(Something*) initWithCapacity : (int)n
{
	int i;
	self = [super init];
	array = (Dot**)malloc(n * sizeof(Dot*));
	for (i = 0; i < n; ++i)
	{
		array[i] = [[Dot alloc] init];
		array[i].x = i;
		array[i].y = i * i;
	}
	return self;
}

@end


int main (int argc, const char * argv[]) 
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	Something* something = [[Something alloc] initWithCapacity: 10];

	int i;
	for (i = 0; i < 10; ++i)
	{
		NSLog(@"array[%i] = %i, %i", i, something.array[i].x, something.array[i].y); 
	}
		
	[something release];
    [pool drain];
    return 0;
}

Open in new window

0
 
pgnatyukCommented:
I added dealloc
#import <Foundation/Foundation.h>

@interface Dot: NSObject
{
	int x;
	int y;
}

@property int x, y;

@end;

@implementation Dot

@synthesize x, y;

@end

@interface Something : NSObject
{
	int capacity;
	Dot** array;
}

@property (nonatomic, assign) Dot** array;

- (Something*) initWithCapacity : (int)n;
- (void) dealloc;

@end

@implementation Something

@synthesize array;

-(Something*) initWithCapacity : (int)n
{
	int i;
	self = [super init];
	array = (Dot**)malloc(n * sizeof(Dot*));
	for (i = 0; i < n; ++i)
	{
		array[i] = [[Dot alloc] init];
		array[i].x = i;
		array[i].y = i * i;
	}
	capacity = n;
	return self;
}


- (void) dealloc
{
	int i;
	for (i = 0; i < capacity; ++i)
	{
		[array[i] release];
	}
	free(array);
	[super dealloc];
}

@end


int main (int argc, const char * argv[]) 
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	Something* something = [[Something alloc] initWithCapacity: 10];

	int i;
	for (i = 0; i < 10; ++i)
	{
		NSLog(@"array[%i] = %i, %i", i, something.array[i].x, something.array[i].y); 
	}
		
	[something release];
    [pool drain];
    return 0;
}

Open in new window

0
 
tiggr009Author Commented:
Great work exactly what I was wanting.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now