Persisting issue with forward class warnings

Discussion in 'iOS Programming' started by AndyCodez, Aug 9, 2009.

  1. AndyCodez macrumors regular

    Joined:
    Aug 6, 2009
    #1
    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 :)
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    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.
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    Can we see your Class.h file, as well as the .h and .m where your @class and #import directives are?
     
  4. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #4
    I will post them when I get home from work today :)
     
  5. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #5
    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!
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    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.
     
  7. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #7
    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!
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    So, did you get this working? If so, what does your Globals.h file look like now?
     
  9. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #9
    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.
     
  10. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #10
    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.
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #11
    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.
     
  12. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #12
    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?
     
  13. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #13
    I did.

    I don't think so.
     
  14. AndyCodez thread starter macrumors regular

    Joined:
    Aug 6, 2009
    #14
    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?
     

Share This Page