I was just wondering if this is possible... if I have a "Static class" (a class with a bunch of static methods) is it possible to have a class variable and access it through one of the static methods?
I am getting a warning of "instance variable accessed in class method".
I maybe just not getting it. Is there anyone that can answer this question?
You can use static variables to implement the equivalent of class variables:
// Foo.h
#interface Foo : NSObject {
}
+ (NSObject*)classVariable;
#end
// Foo.m
#import "Foo.h"
static NSObject* classVariable;
#implementation Foo
+ (NSObject*)classVariable {
return classVariable;
}
#end
Related
Here's my question.
Let's say I have a class called WebServiceBase.h. And I need to add a iVar in to that class called NSString *requestData. But I don't need to add that iVar in to the header file and make it visible to the external people. (If I'm distributing this as a class library)
Also I need to be able to access this requestData iVar, within the other classes that is extended from the WebServiceBase.h. (These extended classes are written by me. Not from the external people)
I tried with declaring the requestData iVar within the class extensions. But then it's not visible to the extended classes.
Any solution for this? I need to protect my data and make it hide from the external world.
You can define your ivars as protected via the #protected keyword, meaning that your class and all subclasses can access it without any problem, but the compiler won't allow this for other classes which don't inherit from your base class:
#interface Foo : NSObject
{
#protected
NSObject *a;
}
Its as simple as that and already gives you all the safety you can get from Objective-C.
You can have an ivar definition block in the #implementation block.
there are 2 ways , you can choose one you like.
1).h file
#interface YourClass
{
}
.m file
#interface YourClass ()
#property (nonatomic, retain) NSString *title;
#end
#implementation YourClass
#synthesize title;
//your method
2) .h flie
#interface YourClass
{
}
.m file
#implementation YourClass
{
NSString *title;
}
//your method
Declare a class extension that defines the ivar in another .h file. Call it something like myclass-private.h. Then import that header in both your main class your subclasses.
I am from C# background, and I am having a hard time in figuring out about how to use a static variable(BOOL in my case) in Objective C.
My questions are:
Where should I declare my static variable.
How can I access(set its value) from another class.
Do I need to use extern keyword.
Declare static variable in your implementation file and provide class method to set/get vlaue of it.
// MyClass.h
#interface MyClass : NSObject {
}
+ (BOOL)gBoolean;
+ (void)setGBoolean:(BOOL)value;
#end
// MyClass.m
#import "MyClass.h"
static BOOL gBoolean;
#implementation MyClass
+ (BOOL)gBoolean; {
return gBoolean;
}
+ (void)setGBoolean:(BOOL)value; {
gBoolean = value;
}
#end
Take a look at this answer.
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?
DataController.h
#class Play;
#interface DataController : NSObject
- (unsigned)countOfList;
- (Play *)objectInListAtIndex:(unsigned)theIndex;
#end
DataController.m
#import "DataController.h"
#import "Play.h"
#interface DataController ()
#property (nonatomic, copy, readwrite) NSMutableArray *list;
- (void)createDemoData;
#end
#implementation DataController
#synthesize list;
- (id)init {
if (self = [super init]) {
[self createDemoData];
}
return self;
}
Why do you think that #interface is defined twice? And also whats the meaning of ()? Shouldn't there be a class name maybe the super class between the parentheses?
In general, the syntax #interface ClassName (CategoryName) is for declaring a category. Categories are a way to add methods to a class. You can do this even with classes for which you don't have the source code. See more here.
#interface ClassName () (with nothing in the parentheses) is essentially a special case of a category and is called a class extension. The primary difference between a class extension and a category is that methods declared in a class extension must be defined/implemented in the main #implementation block for the class, or you'll get a compiler warning. Methods in a regular category can be defined in an external #implementation block.
The most common use for class extensions (as in this case) is for declaring private methods. Objective-C doesn't have support for true private methods, so an easy way to accomplish the same basic end result is to declare private methods in a class extension at the top of the .m file. Since these methods aren't defined in the .h file, other classes won't see them, and you'll get a compiler warning if you try to use them outside the class they belong to.
You can also redeclare a readonly #property as readwrite in a class extension. That way, code external to the class implementation can only read a property's value, but inside the class's implementation, you can write to it too. This is the only case where it's allowable to redeclare an #property.
(Note that class extensions were a new feature in Objective-C 2.0 and aren't available on Mac OS X 10.4 and earlier.)
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.