Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

buldre

macrumors newbie
Original poster
Jan 25, 2010
28
0
Hi! Im working on an gesture recognition application which in short terms do the following;

- gather accelerometerdata when a button is pushed/released and stores this "sample of data". Then the user can do this for a few times and then when he has made enough "sample runs", i make a template out of it using median. After this is made the user pushes a new button performs a gesture, and then the two are compared to check how related the template and "probe" gesture is.

This is a small part of my overall project, and i had it "finished" in simulator, and tested that everything worked fine with feeding it data manually.

When i now went live on my Ipod Touch, the application hans when its supposed to generate the template and provides me with the following error message;


2010-02-01 15:50:36.092 Accelerate[1279:207] *** -[NSCFArray xmedianarray]: unrecognized selector sent to instance 0x126a10
2010-02-01 15:50:36.101 Accelerate[1279:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray xmedianarray]: unrecognized selector sent to instance 0x126a10'

I've tried debugging where it comes from and i traced it to here;

Code:
-(void) addToMedianTemplate: (template *) temp: (int) i{ // intermediate function for the median calculation

NSDecimalNumber *tmpval;

     if([xarray count]-1 >= i){

     tmpval = [xarray objectAtIndex:i];

     [temp.xmedianarray addObject:tmpval]; [B]// HERE IS ERROR[/B]

     tmpval = [yarray objectAtIndex:i];

     [temp.ymedianarray addObject:tmpval];

     tmpval = [zarray objectAtIndex:i];

     [temp.zmedianarray addObject:tmpval];

               }

     

}

which is called in the following fashion;

Code:
-(IBAction)GenTemplate{ // median compare     



     int longest_array=0;

for(storage  *stor ingestures){

          int x = [stor arraylength:'x'];

          if(longest_array < x)

               longest_array =x;

     }



     for(int i=0; i <longest_array; i++){

for(storage  *stor2 ingestures){

               [stor2 addToMedianTemplate:temp:i];

          }

          [temp sort_array];

          [temp mediancalc];



// clear the temp arrays before moving on to next i (x,y,z value instance)

               [temp .xmedianarrayremoveAllObjects];

               [temp .ymedianarrayremoveAllObjects];

               [temp .zmedianarrayremoveAllObjects];

     }
}



I have 4classes; accelerateappdelegate class, probe class, template class, and a storage class.

which are defined as follows;

Code:
@interface storage : NSObject {

     

NSMutableArray *xarray;

NSMutableArray *yarray;

NSMutableArray *zarray;

     

}

@interface AccelerateAppDelegate : NSObject <UIApplicationDelegate,UIAccelerometerDelegate> {

          

UIWindow *window;

     

 IBOutletUILabel *xLabel;

 IBOutletUILabel *yLabel;

 IBOutletUILabel *zLabel;

 IBOutletUILabel *Total;

 IBOutletUILabel *decision;

IBOutlet UILabel *difference;

int pushed,pushed2;

IBOutlet UIActivityIndicatorView * act;

IBOutlet UIButton *startbutton;

IBOutlet UIButton *gentempbutton;

IBOutlet UIButton *probebutton;

NSMutableArray *gestures;

storage *run;

template *temp;

probe *probee;

     



}


@interface probe : NSObject {



NSMutableArray *probex;

NSMutableArray *probey;

NSMutableArray *probez;

}



@property (copy) NSMutableArray *probex;

@property (copy) NSMutableArray *probey;

@property (copy) NSMutableArray *probez;



 @interfacetemplate : NSObject {



// The arrays below hold the template of the gesture for this session

NSMutableArray *templx;

NSMutableArray *temply;

NSMutableArray *templz;

     

NSMutableArray *xmedianarray;

NSMutableArray *ymedianarray;

NSMutableArray *zmedianarray;



     

}



@property (copy) NSMutableArray *templx;

@property (copy) NSMutableArray *temply;

@property (copy) NSMutableArray *templz;

@property (copy) NSMutableArray *xmedianarray;

@property (copy) NSMutableArray *ymedianarray;

@property (copy) NSMutableArray *zmedianarray;


Note: i just took out the informatoin i though would be valuable for you to see, if you want i can post the entire code, if you cannot see the problems here. I get no errors or warnings when compiling in Xcode.

I must note that i recently migrated over to the apple platform, and that therefore my programming skills in Cocoa/ObjC is not top notch. The error is probably some noob mistake, but i really hope you take the time to help me anyways, it is greatly appreciated! :)

Thank you in advance
 
I think the problem is in the way i pass the (template) *temp parameter (an poiner to an instance of the class template). But i dont know how to do this properly in ObjC?

However, that does not explain why it worked fine in my tests(where i manually fed the accelerometers into my arrays).
 
I think the problem is in the way i pass the (template) *temp parameter (an poiner to an instance of the class template). But i dont know how to do this properly in ObjC?

However, that does not explain why it worked fine in my tests(where i manually fed the accelerometers into my arrays).

No, that looks fine. The problem is most likely in if/how you are initializing your temp object, which is not shown.
 
hi!

i do this by;

Code:
temp =[template new];
[temp init];

in my - (void)applicationDidFinishLaunching:(UIApplication *)application function.

where;

Code:
-(void) init{
templx = [NSMutableArray new];
temply = [NSMutableArray new];
templz = [NSMutableArray new];

// temp arrays which contains all "i" index objects
xmedianarray = [NSMutableArray new];
ymedianarray = [NSMutableArray new];	
zmedianarray = [NSMutableArray new];	
}

Its the same way is initialize the instances of the other classes also, but its only here i have this problem...

could this have anything to do with the fact that it is only in the template class i make properties and sanitize the 6 arrays above?

Ty so much for the help!
 
i thought the new function added them to the autorelease and hence took care of this for me?
 
i thought the new function added them to the autorelease and hence took care of this for me?

No. See the note from NSObject new function description:

"Special Considerations
If you are using managed memory (not garbage collection), this method retains the object before returning it. The returned object has a retain count of 1 and is not autoreleased. The invoker of this method is responsible for releasing the returned object, using either release or autorelease."
 
hi!

i do this by;

Code:
temp =[template new];
[temp init];

in my - (void)applicationDidFinishLaunching:(UIApplication *)application function.

where;

Code:
-(void) init{
templx = [NSMutableArray new];
temply = [NSMutableArray new];
templz = [NSMutableArray new];

// temp arrays which contains all "i" index objects
xmedianarray = [NSMutableArray new];
ymedianarray = [NSMutableArray new];	
zmedianarray = [NSMutableArray new];	
}

Its the same way is initialize the instances of the other classes also, but its only here i have this problem...

could this have anything to do with the fact that it is only in the template class i make properties and sanitize the 6 arrays above?

Ty so much for the help!

As described by the NSObject new function description [ClassName new]; is merely shorthand for [[ClassName alloc] init];

However if you inspect the NSMutableArray class description you will see that init is *not* one of the available options for instantiating a new class, you must use initWithCapacity, or arrayWithCapacity. I suspect this may be the root of your problem.

Try this instead:

xmedianarray = [[NSMutableArray alloc] initWithCapacity:0];
 
Hi! Thanks for all your help, ur tips pointed me in the right direction. Actually, the problem was that my void init method had the same name as the standard framework method, and hence it was never run completely :)
 
Actually, the problem was that my void init method had the same name as the standard framework method, and hence it was never run completely :)
It's allowed to have the same name, actually. That's how a subclass overrides the method of a superclass. But normally you also call that method of the superclass as part of the code for the override. Quite often you will see something like below for an init override:
Code:
- (id)init {
    if (self = [super init]) {
        // Custom initialization
    }
    return self;
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.