ios - How to declare static variable? [duplicate] - iphone

This question already has answers here:
What's the meaning of static variables in an implementation of an interface?
(4 answers)
Closed 9 years ago.
Static Variable declared in C# like this :
private const string Host = "http://80dfgf7c22634nbbfb82339d46.cloudapp.net/";
private const string ServiceEndPoint = "DownloadService.svc/";
private const string ServiceBaseUrl = Host + ServiceEndPoint;
public static readonly string RegisteredCourse = ServiceBaseUrl + "RegisteredCourses";
public static readonly string AvailableCourses = ServiceBaseUrl + "Courses";
public static readonly string Register = ServiceBaseUrl + "Register?course={0}";
How to call this static variable in another class ?

Answer : use the static keyword.
Syntax : static ClassName *const variableName = nil; ( Updated [ Added const] as per the Comment by Abizern )
Reason for update ( As per the comments by "Till " ) :
static when being used on a variable within a function/method will preserve its state even when the scope of that variable is left. When being used outside any function/method, it will make that variable invisible to other source files - it will be visible within that implementation file only when being used outside any function/method.
Hence a const with static helps the compiler to optimize it accordingly.
If you need more explanation on use of const with static, I found one beautiful link here : const static.
Use:
You might have seen the use of "static" keyword in your tableview's delegate - cellForRowAtIndexPath:
static NSString *CellIdentifier = #"reuseStaticIdentifier";

static NSString *aString = #""; // Editable from within .m file
NSString * const kAddressKey = #"address"; // Constant, visible within .m file
// in header file
extern NSString * const kAddressKey; // Public constant. Use this for e.g. dictionary keys.
To my knowledge public statics aren't a built-in feature of Objective-C. You can work around this by making a public class method that returns the static variable:
//.h
+ (NSString *)stringVariable;
//.m
static NSString * aString;
+ (NSString *)stringVariable
{
return aString;
}
Most static objects can't be initialized at compile time (I think only strings actually). If you need to initialize them, you can do so in the + (void)initialize method, which lazily gets called whenever that class is first referenced.
static UIFont *globalFont;
+ (void)initialize
{
// Prevent duplicate initialize http://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html
if (self == [ClassName class]) {
globalFont = [UIFont systemFontOfSize:12];
}
}

Objective C is super set of C/C++ , so for static it follows C++/C convention, you should be able to use it
static <<datatype>> <<variableName>> = initialization
Hoping you would have tried this way , have you got any error, if yes, please add more clarity in your question
if thats case with NSString use following,
static NSString *pString = #"InitialValue";
and if you have to modify NSString in your code, make sure it must be NSMutableString.
Hope that's help ...

Related

Static Members in a Global class

export class Globals
{
static m_Name : string = "Hello world";
static m_Version : number = 1.0;
static m_Canvas : HTMLCanvasElement = null;
static m_Foo : Foo = null;
}
public OnDocumentLoad() : void
{
Globals.m_Canvas = <HTMLCanvasElement>document.getElementById('myCanvas');
Globals.m_Foo = new Foo(m_Name, m_Version);
}
Is this acceptable use of static in TypeScript? I'm unsure of what static is doing in this case other than making the member variables class members that everyone can access regardless of instance. But, for example, is m_Foo and m_Canvas valid instances within the Globals class, kind of like singletons so to speak (without any undefined checking and presumably anytime after OnDocumentLoad of course)
Originally I didn't have Globals as a class and they were just generic var declarations I had in a .ts file I was referencing everywhere. But I wanted to organize them into a nice little Globals class. This works in my experience testing it so far, but I wanted to see if there was anything I was missing about what static is doing here.
The most I found on the subject was here in the Specification:
http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf
Member declarations with a static modifier are called static member declarations. Static property
member declarations declare properties in the constructor function type (section 8.2.5), and must specify
names that are unique among all static property member declarations in the containing class, with the
exception that static get and set accessor declarations may pairwise specify the same name.
Note that the declaration spaces of instance and static property members are separate. Thus, it is possible
to have instance and static property members with the same name
From that I gleam that you can make an instance of Globals and its members will have a different meaning from just calling the Globals.m_Name for example, but I don't intend to do that here.
If you want to create a namespace object, use module:
export module Globals
{
export var m_Name : string = "Hello world";
export var m_Version : number = 1.0;
export var m_Canvas : HTMLCanvasElement = null;
export var m_Foo : Foo = null;
}

Adding custom behavior and state to all my classes

I want to add functionality and another property to ALL of my classes.
So I wrote a category:
#implementation NSObject (MyCategory)
And I declared a static property in it:
static MyObj myObj;
And I created 2 class methods to get and set it:
+ (MyObj) getMyObj {
return myObj;
}
+ (void) setMyObj:(MyObj)obj {
myObj = obj;
}
Now I imported NSObject+MyCategory.h in my .pch file, so all classes will be effected by this. Indeed all classes now have the new functionality and state:
#import "NSObject+MyCategory.h"
The problem is that when I set myObj, it changes myObj on all classes. All classes share 1 myObj.
I want each class to have its own myObj that is added using the category. I don't want one myObj, rather I want as many myObj's as classes. Each class should have its own myObj.
Thanks,
Nur
You can not add properties instance variables to a class in categories. Either subclass NSObject or use associated objects.
Your solution adds a single static variable (not "property", in Objective-C that means something else), there is no way using categories to add a static variable per class.
However your idea is close to what will work for you; if you can only have one variable and want to store many values what can you use? A dictionary.
static NSMutableDictionary *References;
+ (void) load
{
// load is called exactly once when this category is first loaded,
// setup the dictionary
References = [NSMutableDictionary new];
}
+ (void) setMyObj:(MyObj)reference
{
// NSMutableDictionary will take any object reference as a key,
// for a class method self is a reference to the unique class object,
// so use self as the key and store the reference
[References setObject:reference forKey:self];
}
+ (MyObj) getMyObj
{
// returns previously stored reference or nil if there isn't one for this class
return [References objectForKey:self];
}
HTH

How to make a ConstantList Class in Objective C

How to make a ConstantList class in Objective C of an application which could be accessible to all the classes who are using constants.
like in Actionscript we do:
public class ConstantList
{
public static const EVENT_CHANGE:String = "event_change";
}
Or what is the best approach to handle application constant.
Regards
Ranjan
You can use global constants, like the following:
//MyConstants.m
NSString * const EVENT_CHANGE = #"event_change";
// MyConstants.h
extern NSString* const EVENT_CHANGE;
Now include MyConstants.h header to your implementation file and you can use EVENT_CHANGE constant string in it
I would recommend Vladimir's approach.
Just for completeness: You can do it as a class like this:
#interface Constants : NSObject {
}
+ (NSString*)aConstantString;
#end
#implementation Constants
+ (NSString*)aConstantString {
return #"This is always the same and accessible from everywhere";
}
#end
You access the value like:
NSString* string = [Constants aConstantString];

iPhone static libraries: How to hide instance variable

I'm creating a static library to share using the following guide:
http://www.amateurinmotion.com/articles/2009/02/08/creating-a-static-library-for-iphone.html
In one of the functions, I return a "SomeUIView" which is a subclass of UIView and is defined in the public header, however I don't want to expose the internal instance variable of SomeUIView in the public header.
I've tried using categories for a private internal header file for SomeUIView, but I keep running into "Duplicate interface declaration for class 'SomeUIView'".
Does anyone know how to do this?
Thanks!
Categories and extensions can't add instance variables to a class. I'd go for the PIMPL idiom here - use a private implementation object:
// header
#class MyObjImpl;
#interface MyObj {
MyObjImpl* impl;
}
#end
// implementation file:
#interface MyObjImpl {
id someIvar;
}
// ...
#end
// ... etc.
This also keeps your public interface stable in case you want to add something for internal use.
The "duplicate interface" comes from missing parentheses in the second interface declaration:
// header:
#interface MyObj
// ...
#end
// implementation file:
#interface MyObj () // note the parentheses which make it a class extension
// ...
#end
You may also use the Objective-C 2 feature known as "Associative reference".
This is not really object-oriented API, but you can add/remove object to another object by using some simple functions of the runtime:
void objc_setAssociatedObject(id object, void * key, id value)
Sets the value or remove it when value is nil.
id objc_getAssociatedObject(id object, void * key)
Retrieve the value for specified key.
Note that this is also a mean to add "instance variable" to existing object when implementing a category.
Key is s simple pointer to private variable that you can declare as a module private by using:
static char SEARCH_INDEX_KEY = 0;

Objective C confusion - Setting sythesized vars to ivars

I've noticed in some of the examples ive seen that you will set a engine( class variable ) to a _engine ( ivar ). I don't get it. What's going on here?
Here is an example of what I'm saying:
#synthesize engine = _engine, delegate = _delegate
This syntax maps a property to an instance variable (ivar) with a different name.
So:
#synthesize engine = _engine;
will create property accessor methods that access the _engine ivar instead of engine. You can still access the propery as:
object.engine
More info in the Apple developer documentation on properties (section Property Implementation Directives)
The author wanted to make sure that there was no confusion between accessing the ivar directly and accessing via the setter/getter. If the names are the same, the usual case, it is easy to write:
engine = 0 instead of self.engine = 0; For an ivar that needs to be retained such as NSString this can cause errors in the retain counts.
There is also historic precedence of naming ivars with a leading "_", "m" or "f" so they wpuld be readily recognized as ivars.
The #synthezise keyword tells the Objective-C compiler to generate a getter and a setter method for your property. If you have defined:
#property(copy,nonatomic) NSString* name;
Then #synthesize name; will create these two methods for you, so that you do not have to implement them:
-(NSString*)name;
{
return name;
}
-(void)setName:(NSString*)newName;
{
if (name != newName) {
[name release];
name = [newValue copy];
}
}
By default the name of the instance variable that is used as the backing store for the synthesized property is named the same as the property. This is not always what you want, and you can then synthesize as #synthesize name = _otherName; to tell the compiler to instead generate this code for you:
-(NSString*)name;
{
return _otherName;
}
-(void)setName:(NSString*)newName;
{
if (_otherName != newName) {
[_otherName release];
_otherName = [newValue copy];
}
}
The reason you usually prefix the instance variables that are used as backing stores for properties with a underscore character '_' is to make help you to remember not to access them directly.
If the name of the ivar does not exactly match the name of the synthesized var then you need to map the ivar to the var. You might want to do this if you like prefixing your ivars with an underscore.