Undeclared variable from base class when derived class has property - iphone

I have the following code below, where a base class has a member which is (should be) accessible by a derived class.
The code below however gives a compilation error
...abcAppDelegate.m:30: error: 'baseVal_' undeclared (first use in this function)
If I call the variable using self->baseVal_ or if I remove the property defined in the derived class then everything is ok.
Also, if I define a category of the derived class, then I can access baseVal_ without error.
//---------------------------------------------------------------
// BASE CLASS
//---------------------------------------------------------------
#interface BaseClass : NSObject
{
#protected
BOOL baseVal_;
}
#end
#implementation BaseClass
#end
//---------------------------------------------------------------
// DERIVED CLASS
//---------------------------------------------------------------
#interface DerivedClass : BaseClass {
}
#property (readwrite) BOOL val;
#end
#implementation DerivedClass
#synthesize val;
- (void) foo {
baseVal_ = YES;
}
#end

Have a look here: Click. Seems to possibly be a bug with GCC, but it's easily fixable by adding val as an instance variable instead of using the property without.

Related

ios - How to assign a new class in existing class?

I'm new to iPhone development,I want to assign one class in existing class
This is what declare in C#
public partial class UserRegisteration : System.Web.UI.Page
{
//some methods
public class Mime
{
//some methods
}
}
like the above format in Objective-C how to assign one more class in existing class?
Any ideas? Thanks in advance.
Yes you can.I am using one class in existing class . One is extending UIView and other is extending NSObject.
MultiLayout.h
#interface MultiLayout : UIView
{
// methods and properties
}
#end
#interface SingleControl : NSObject
{
// methods and properties
}
#end
MultiLayout.m
#implementation SingleControl
//methods and variables declaration and property synthesization
#end
#implementation MultiLayout
//methods and variables declaration and property synthesization
#end
For getting the static value of SingleControl in MultiLayout . you have to call class method like:
MultiLayout.h
#interface MultiLayout : UIView
{
// methods and properties
}
#end
#interface SingleControl : NSObject
{
// methods and properties
}
// add class method
+(int)getValue;
#end
MultiLayout.m
#implementation SingleControl
// add static value
static int values = 100;
// implement method
+(int)getValue{
return values;
}
#end
#implementation MultiLayout
// call method to get value
[SingleChoiceControl getValue];
#end
If I understand your question correctly, you would do this in your interface file:
#interface Mime
//properties and method declarations
#end
#interface UserRegistration : System.Web.UI.Page
#property (strong, nonatomic) Mime *mimeInstance;
#end
and then in the implementation file you implement both like so:
#implementation Mime
//implementation
#end
#implementation UserRegistration
//implementation
#end

Issue when calling a method with return type “void” in same file

I am getting an issue when calling a method of return type -(void) in same class
Issue is:Instance method - someMethodName not found (return type defaults to 'id')
Declare someMethodName in your .h file.
The problem is that Xcode can't find a declaration for the method. In most recent version of Xcode you don't need to provide a declaration for a method if the implementation is in the same .m that you are calling it from. e.g.:
//ExampleClass.m
#implementation ExampleClass
-(void)aMethod {
[self anotherMethod]; //Xcode can see anotherMethod so doesn't need a declaration.
}
-(void)anotherMethod {
//...
}
#end
However in earlier version of Xcode you would need to provide a declaration. You can do this in the #interface in .h file:
//example.h
#interface ExampleClass : NSObject
-(void)anotherMethod;
#end
The problem with putting the declaration in the .h is that all other class can see the method, which may cause problems. To get around this you can declare a class continuation within the .m:
//ExampleClass.m
#interface ExampleClass ()
-(void)anotherMethod;
#end
#implementation ExampleClass
//...
#end

Incorrect use of static variables?

Class A has a UIImage.
Class B has a static reference to a class of type A.
Before class B is instantiated, I want to call a static method in class B to assign an instance of class A.
+ (void)setClassAReference:(ClassA*)classA
{
classA_ = classA;
}
Is this possible?
Before I delved into my current project, I created a sample one, and was able to set an integer value, then instantiate B with it keeping the stored value and allowing access to it.
However, in my current project, XCode refuses to allow me to pass an integer value:
Non-static method in class A:
- (UIImage*)imageWithIdentifier:(ImageIdentifier)identifier; // identifier is enum type
After class B is instantiated, I try to call a method in A:
UIImage *img = [classA_ imageWithIdentifier:ImageIdentifier_Foo];
But I get an implicit conversion warning. The auto-complete shows (id) instead of (ImageIdentifier). I've triple-checked all my method signatures and they all use the enum type.
Am I using static variables incorrectly or is there another problem? I realize I could use a singleton, but I'd prefer not to if possible.
I'm adding the enum declaration here:*
typedef enum
{
ImageIdentifier_Foo = 0,
ImageIdentifier_Bar
} ImageIdentifier;
*real names changed to protect the innocent.
Firstly...
If you want to initialize static variables on a class before it is instantiated you use the class method on NSObject
+ (void) initialize
This is where you can assign your static ClassA variable in ClassB.
Secondly....
Make sure you retain that classA variable, otherwise it will be released.
Thirdly.....
Regarding your implicit conversion... what is variable 'a', above this you wrote classA_. Can you show your enum declaration. Have you imported ClassA ?
I don't have any compile error with this:
ClassA.h
typedef enum
{
ImageIdentifier_Foo = 0,
ImageIdentifier_Bar
} ImageIdentifier;
#interface ClassA : NSObject
- (UIImage*)imageWithIdentifier:(ImageIdentifier)identifier; // identifier is enum type
#end
ClassA.m
#import "ClassA.h"
#implementation ClassA
- (UIImage*)imageWithIdentifier:(ImageIdentifier)identifier {
return nil;
}
#end
ClassB.h
#interface ClassB : NSObject
#end
ClassB.m
#import "ClassB.h"
#import "ClassA.h"
static ClassA *classA;
#implementation ClassB
+ (void) initialize {
classA = [[ClassA alloc] init];
}
- (void) doSomething {
UIImage *image = [classA imageWithIdentifier:ImageIdentifier_Foo];
NSLog(#"image %#", image);
}
#end
The error got cleared up.
I was importing Class A in the .h file of Class B. It was also being imported in the .m file of class B. I removed the import in the .h file, and changed it to #class ClassA and everything automagically resolved itself.
Would a circular reference have caused this?

warnings in iphone sdk

i'm getting this two messages:
warning: 'MainView' may not respond to '-switchToNoGridView'
Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments
1st here:
//GridView.m
#import "GridView.h"
#import "MainView.h"
#implementation GridView
-(IBAction)switchToNoGridView {
[mainView switchToNoGridView];
}
#end
2nd here:
warning: 'MainView' may not respond to '-goBack'
Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments
in this:
//NoGridView.m
#import "NoGridView.h"
#import "MainView.h"
#implementation NoGridView
-(IBAction)goBack {
[mainView goBack];
}
#end
how to avoid these warnings?
Have you declared switchToNoGridView and goBack in the class interface for MainView?
This warning means that the method signatures could not be found in the class of the instance that you are calling the method on; since message dispatch in Objective-C is done at runtime this is allowed, however a warning is shown.
I'm not quite sure from your code, but I think you're encountering one of two errors. Either:
You haven't declared the methods switchToNoGridView or goBack in the MainView class declaration. For Xcode to know that an object responds to a method, you have to include its definition in the class header file, like this:
#interface MainView : ParentObject {
// instance variables
}
// properties
- (void)switchToNoGridView;
- (void)goBack;
#end
This assumes you actually want to declare them as (void), of course - they can have return values, but since you don't do anything with the result of the call in your code, I'm assuming they're void. Or:
You meant to call MainView the class, not mainView the object. Since we can't see your property or instance variable definitions for GridView.h, nor can we see the current method declarations in MainView.h, it's possible that you have a static method +(void)switchToNoGridView and +(void)goBack declared on MainView, but you're calling it on an instance mainView of MainView. For example:
#interface AClass : NSObject { }
+ (void)doSomething;
#end
#implementation AClass
+ (void)doSomething {
NSLog(#"Doing something");
}
#end
#import "AClass.h"
#interface AnotherClass : NSObject {
AClass *aClass;
}
#property(nonatomic,retain) AClass *aClass;
- (void)doSomethingElse;
#end
#implementation AnotherClass
- (void)doSomethingElse {
[aClass doSomething]; // This will break at runtime
[AClass doSomething]; // but this won't
}
#end
Basically, it's possible you've confused class methods with object methods. Either way, you should check your MainView header file for the appropriate method definitions.

Can protocols within protocols be treated as inclusive of the protocol they adopt?

I am assigning protocols in a couple classes that follow an inheritance tree. Like so:
first class
#protocol LevelOne
- (void) functionA
#end
#interface BaseClass : NSObject <LevelOne> {
}
second class
#protocol LevelTwo <LevelOne>
- (void) functionB
#end
#interface SubClass : BaseClass <LevelTwo> {
}
Later I am assigning the class as delegate properties of other classes
base class
#interface AppClass : NSObject {
#protected
id<LevelOne> levelOneDelegate;
}
#property (assign) id<LevelOne> levelOneDelegate;
subclass
#interface AppClassesFriend : AppClass {
#protected
id<LevelTwo> levelTwoDelegate;
}
#property (assign) id<LevelTwo> levelTwoDelegate;
At the end of this journey, AppClassesFriend has 2 properties on it.
"levelOneDelegate" has access to "functionA", when it is assigned with a BaseClass object.
However, I am finding that "levelTwoDelegate" only has access to "functionB" (it is assigned with a SubClass object).
In order to have AppClassesFriend be able to use both functions, it seems I need to assign BOTH a levelOneDelegate AND levelTwoDelegate.
Is there any way to make "levelTwoDelegate" have access to both? Since, both functions are available on "SubClass".
So, what I would like to be able to do is :
SubClass *s = [SubClass alloc];
AppClassesFriend *a = [AppClassesFriend alloc];
a.levelTwoDelegate = s;
so inside AppClassesFriend (a) I could use :
[self.levelTwoDelegate functionA]; <---- this is never found
[self.levelTwoDelegate functionB];
but it seems I have to add
a.levelOneDelegate = s;
Thanks if anyone took the time to read all the way down this far. So in summary the question is, how do I get "levelTwoDelegate" to have access to both functionA and functionB?
Simply declare that your subclass's delegate property implements both level one and level two protocols (i.e. implements both functionA and functionB):
#interface AppClassesFriend : AppClass {
#protected
id<LevelOne,LevelTwo> levelOneAndTwoDelegate;
}
#property (assign) id<LevelOne,LevelTwo> levelOneAndTwoDelegate;