Reputation: 39671
thing.h
@interface Thing : NSObject
{
float stuff[30];
}
@property float stuff;
@end
thing.m
@implementation Thing
@synthesize stuff;
@end
I get error: type of property 'stuff' does not match type of ivar 'stuff'
I don't want to use an NSArray because I'd have to make the floats into NSNumbers (right?) and that's a pain to do math with.
Update: I've noticed similar answers had guesses and trial answers. While I appreciate the attempts by non-Objective-C folks, I'm hoping for a definitive answer whether it's possible or not.
Upvotes: 2
Views: 8421
Reputation: 1069
Daniel's FloatHolder answer has a major bug (edit: he's now fixed it). It only allocates memory for one float and not for the whole array.
The line:
_values = malloc(sizeof(float));
Should be:
_values = malloc(sizeof(float) * count);
Otherwise it seems to be a good answer. Sorry couldn't work out how to reply directly. (edit: I didn't have the necessary privilege on stackoverflow then.)
Upvotes: 2
Reputation: 4967
OK, I have compiled up the following code at it works as expected.
FloatHolder.h
@interface FloatHolder : NSObject {
int _count;
float* _values;
}
- (id) initWithCount:(int)count;
// possibly look into this for making access shorter
// http://vgable.com/blog/2009/05/15/concise-nsdictionary-and-nsarray-lookup/
- (float)getValueAtIndex:(int)index;
- (void)setValue:(float)value atIndex:(int)index;
@property(readonly) int count;
@property(readonly) float* values; // allows direct unsafe access to the values
@end
FloatHolder.m
#import "FloatHolder.h"
@implementation FloatHolder
@synthesize count = _count;
@synthesize values = _values;
- (id) initWithCount:(int)count {
self = [super init];
if (self != nil) {
_count = count;
_values = malloc(sizeof(float)*count);
}
return self;
}
- (void) dealloc
{
free(_values);
[super dealloc];
}
- (float)getValueAtIndex:(int)index {
if(index<0 || index>=_count) {
@throw [NSException exceptionWithName: @"Exception" reason: @"Index out of bounds" userInfo: nil];
}
return _values[index];
}
- (void)setValue:(float)value atIndex:(int)index {
if(index<0 || index>=_count) {
@throw [NSException exceptionWithName: @"Exception" reason: @"Index out of bounds" userInfo: nil];
}
_values[index] = value;
}
@end
then in your other application code you can do something like the following:
** FloatTestCode.h **
#import <Cocoa/Cocoa.h>
#import "FloatHolder.h"
@interface FloatTestCode : NSObject {
FloatHolder* holder;
}
- (void) doIt:(id)sender;
@end
** FloatTestCode.m **
#import "FloatTestCode.h"
@implementation FloatTestCode
- (id) init
{
self = [super init];
if (self != nil) {
holder = [[[FloatHolder alloc] initWithCount: 10] retain];
}
return self;
}
- (void) dealloc
{
[holder release];
[super dealloc];
}
- (void) doIt:(id)sender {
holder.values[1] = 10;
}
Upvotes: 8
Reputation: 400264
You can't do it the way you want to do it. You can jump through some hoops and get something similar, e.g. using Daniel's solution, but it's not quite the same thing. The reason you can't do it is that arrays are not lvalues in C. An lvalue is something that can appear on the left-hand side of an assignment. The following code is invalid C:
float stuff1[30], stuff2[30];
stuff1 = stuff2; // ERROR: arrays are not lvalues
As a consequence, you can't declare properties whose types are not lvalues.
Upvotes: 2
Reputation: 21579
Even if you could get that to compile, it wouldn't behave well. 'stuff' would return a float*, and the client would have no idea how long the array way; 'setStuff:' would just change the pointer, and you'd either be pointing to stack-allocated data that would vanish out from under you or heap-allocated data that would leak because it wouldn't know to free it.
Upvotes: 1
Reputation: 4967
The type of the property must match the type of the instance variable it will be stored in, so you could do something like
@interface Thing : NSObject
{
float stuff[30];
}
@property float[30] stuff;
@end
and it should work. I wouldn't recommend it though. I'm guessing you're looking for something like indexed properties from Delphi. The closest you'll get is something like the following.
@interface Thing : NSObject
{
float stuff[30];
}
- (void) setStuff:(float)value atIndex:(int)index;
- (float) getStuffAtIndex:(int)index;
@end
Upvotes: 6
Reputation: 410652
I'm not well-versed in Objective-C 2.0, but I'm guessing that the issue might be caused by the fact that a C array is essentially just a pointer to the first element of the array, meaning that the type of float stuff[30]
is actually float *
, not merely a float
.
Upvotes: 0