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

AndyCodez

macrumors regular
Original poster
Aug 6, 2009
187
0
I've been getting the following warning for a while now:

"Warning: Receiver 'Class' is a forward class and corresponding @interface may not exist"

I have @class in the header file, and have the import in the implementation file.

The class being called is just a class full of methods that i use. They are mostly class methods. I use this class for storing variables for use later, if this makes any difference. Sometimes when I compile the warnings will not show up but other times they will. Often times it is when I make a modification to the implementation file they are called from.

This is driving me nuts! Please help! If there is any more information needed to assist me in this matter please ask :)
 
I assume that that error just means that there is no @implementation in scope for the class. You need to check that the #import in your implementation file is correct. Maybe there's a spelling error somewhere or something else like that.
 
Can we see your Class.h file, as well as the .h and .m where your @class and #import directives are?

Globals.h
Code:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Globals : NSObject 
{
		
}

float outputVal;

+ (id) init;
+ (float) doubleVal;
+ (void)setVal:(float)fieldVal; 
+ (NSString*) convertToString:(float) intValue;

+ (void) setHistString:(NSString*) val;
+ (NSString*) getHistString;

@end

Globals.m
Code:
#import "Globals.h"

@implementation Globals

NSString *HistOutputString;


+ (id) init
{
	if(self = [super init])
	{
		outputVal = 0;
	}
	
	return self; 
}


+ (float) doubleVal
{
	return outputVal;
}


+ (void) setVal:(float) fieldVal
{
	outputVal = fieldVal;
}

+ (NSString*) convertToString:(float) intValue
{	
	NSString *stringOutput= [NSString stringWithFormat:@"%.2f", intValue];
	return stringOutput;
}

+ (void) setHistString:(NSString*) val
{
	HistOutputString = val;
}
+ (NSString*) getHistString
{
		if (HistOutputString == nil)
		{
			return @"";
		}
		else
		{
			return HistOutputString;
		}
	
}

@end

Cut down version of TestCalculatorViewController.h
Code:
#import <UIKit/UIKit.h>
@class Globals;

@interface TestCalculatorViewController : UIViewController {
	
	IBOutlet UITextField *txtOutput;
	IBOutlet UIButton *btnOne;
	IBOutlet UIButton *btnTwo;
	IBOutlet UIButton *btnThree;
	IBOutlet UIButton *btnFour;
	IBOutlet UIButton *btnFive;
	IBOutlet UIButton *btnSix;
	IBOutlet UIButton *btnSeven;
	IBOutlet UIButton *btnEight;
	IBOutlet UIButton *btnNine;
	IBOutlet UIButton *btnDivide;
	IBOutlet UIButton *btnMultiply;
	IBOutlet UIButton *btnSubtract;
	IBOutlet UIButton *btnAdd;
	IBOutlet UIButton *btnEnter;
	IBOutlet UIButton *btnZero;
	IBOutlet UIButton *btnClear;
	IBOutlet UIButton *btnDecimal;
	IBOutlet UIButton *btnPower;
	IBOutlet UIButton *btnMem;
	IBOutlet UIButton *btnMemClear;
	IBOutlet UIButton *btnMemAddToScreen;
	IBOutlet UIButton *btnNegPos;

}

Cut down version of TestCalculatorViewController.m
Code:
#import "TestCalculatorViewController.h"
#import "HistoryCalcViewController.h"
#import "HistoryTableViewController.h"
#import "Globals.h"

@implementation TestCalculatorViewController

//Initializing buttons
@synthesize btnEnter, btnOne, btnTwo, btnThree, btnFour, btnFive, btnSix, btnSeven, btnEight, btnPower, btnNegPos;
@synthesize btnNine, btnAdd, btnSubtract, btnMultiply, btnDivide, txtOutput, btnZero, btnClear, btnDecimal, btnMem, btnMemClear, btnMemAddToScreen;

//float equalsNum = 0;
float storedNum;
// 1 = add, 2 = subract, 3 = divide, 4 = multiply
int operation;
NSString *buildHistoryString;

//If memory button is pressed
NSString *strMem;

//Called when the Enter button is pressed
-(IBAction) updateText:(id) sender
{
	
	NSString *DisplayText;
	float value = [txtOutput.text floatValue];	
	
	//Do the operation based on what operation was pressed
	switch(operation)
	{
		case 1:
			value = value + [Globals doubleVal];
			break;
		case 2:
			value = [Globals doubleVal] - value;
			break;
		case 3:
			value = ([Globals doubleVal]/value);
			break;
		case 4:
			value = value * [Globals doubleVal];
			break;
		case 5:
		{
			value = [self mathPowerFunction:[Globals doubleVal] andpower:value];
			break;
		}
		default:
			DisplayText = @"";
	}
	
	//Get the second number that was input
	[HistoryTableViewController setHistoryStringVal2:txtOutput.text];
	
	// Convert the total'd number to a string for display
	DisplayText = [Globals convertToString:(value)];
	
	// Pass the string of the total value to finish off the string for the output screen
	[HistoryTableViewController setHistoryStringTotal:DisplayText];
	
	txtOutput.text = DisplayText;
	
	// Save the total'd value for use in calculations after the current entry
	[Globals setHistString:(DisplayText)];
	
	// Update the history table with the new calculation
	[HistoryTableViewController buildHistoryArray];

	storedNum = 0;
		
}

What I find interesting is while messing around with my globals files / or the view controller.m/.h files with the directives in the files i would compile without warnings. But when I would go in and make a change to the view controller files the warnings would pop back up. Even though the changes made had nothing to do with globals class calls. I don't get it. I think I've tried about every combination of the directives to no avail.

So frustrating!
 
I don't see the problem.

However this line isn't in the right place:

Code:
float outputVal;

place it in the implementation file, outside the implementation block like this

Code:
static float outputVal;

You also have some file scope globals in TestCalculatorViewController.m that should also be outside the implementation block and declared static.
 
Thanks for the standards pointer :) I didn't realize thats where I was supposed to put them! That is what I thought about the class files, I couldn't see where I was in the wrong. I'm using methods from a different view controller class in the one i posted previously and have no problems or warnings.

Later I may try and copy those files into a different name and see if its some weird issue with how they were created. I tried every combination possible with the @class and #import to no avail. I even deleted those from the view controller and it still compiled but with the same warnings. The app functioned properly still as well.

I don't remember having these kinds of issues with c++ when I took a course a few years ago.

Thanks for the pointers!
 
So, did you get this working? If so, what does your Globals.h file look like now?

No I did not get it working. I'm at work so can't make changes, but I did change the variables he mentioned. I'm just confused because it wont show any warnings unless i modify (the .m with the calls to globals) then compile. If i just compile it will not show warnings at the bottom right of xCode.
 
I'm guessing that in some cases the file is being compiled and others it isn't. Files are only compiled if they are modified or a header file they depend on is modified. I assume if you open the file and compile it from the Build -> Compile menu item it always shows the warning.

It should be possible to fix this problem. This is not a compiler bug. There is something wrong with the way your files are set up.
 
No I did not get it working.
Well, I think there must be something else going on in your code because I was able to add your Globals.h and .m that you posted here into a new window-based app and @class Globals; in the appDelegate.h and #import "Globals.h" in the .m and all compiled fine (even after numerous clean builds). Then I tried adding your TestCalculatorViewController code from your post. It required a bunch more work to get compiling without errors or warnings (adding properties for all your synthesized ivars, commenting out unknown imports, etc.) but eventually I got a successful build and no "Receiver 'Globals' is a forward class and corresponding @interface may not exist" warning. If your warning is actually referencing 'Class' and not 'Globals', I think that's a big clue as to the issue.

If you're willing, zip up and attach your project folder and I can try and take a closer look.
 
Well, I think there must be something else going on in your code because I was able to add your Globals.h and .m that you posted here into a new window-based app and @class Globals; in the appDelegate.h and #import "Globals.h" in the .m and all compiled fine (even after numerous clean builds). Then I tried adding your TestCalculatorViewController code from your post. It required a bunch more work to get compiling without errors or warnings (adding properties for all your synthesized ivars, commenting out unknown imports, etc.) but eventually I got a successful build and no "Receiver 'Globals' is a forward class and corresponding @interface may not exist" warning. If your warning is actually referencing 'Class' and not 'Globals', I think that's a big clue as to the issue.

If you're willing, zip up and attach your project folder and I can try and take a closer look.

Oops in the original post I didn't put the actual class name in there it does say 'Globals' not class. You ran the view controller with the calls to Globals with out the warning?

Interesting.. I'm going to create a new globals header/.m files and with the same code tonight and try it out with that to see if it was some wierdo issue.

If this doesn't fix it I will zip it up and send it to you. I can PM Zip files to people right?
 
Ok those warnings are no more!! Yay! Now for the story:

When I got home I ran it and made a change to the view controller (where the warnings were popping up). The warnings appeared.

So I went ahead and deleted the Globals.h and Globals.m. I copied the code from them into the newly added Globals.h and Globals.m and compiled and no warnings of this sort.

I made changes to the view controller and compiled and ran still no warnings. So finally those warnings are taken care of.

I'm not sure as to why they occurred but the deleting and re-adding the files fixed the issue.

How weird is that?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.