Release static int variable - iphone

How to "clean" static int variables in a view class method? Every time a get back to this view I need those vars "zeroed". The [self.view removeFromSuperview];
instruction does not seem enough to free up memory from those vars.
Thank you. Have a great 2010!
These int vars are declared static in a view method. They are not global in the view class.

If you don't want a static value to stick around, don't make it static.

You'll have to manually do this by defining a setValue method similar to:
#interface MyClass
{
// ...
}
+ (NSString *)myVar;
+ (void)setMyVar:(NSString *)newVa;
#end
#implementation MyClass
static NSString *myVar;
+ (NSString *)myVar { return myVar; }
+ (void)setMyVar:(NSString *)newVar { myVar = newVar; }
#end

Related

how to make static variable initialized

I want to save the "dataFilePath" as a static variable so that it can be initialized when first time use "Constants" and no need to instantiate the Class , for example [Constants SDataFilePath]. But the trues is that the init method is not called. How can I do to meet my request? (In Java the construct method will be called the fist time to access the Class).
#implementation Constants
static NSString *dataFilePath;
-(id)init
{
NSLog(#"init!");
if(self = [super init]) {
dataFilePath = [self getDataFilePathWithArg:dbfile];
}
return self;
}
+(NSString *)SDataFilePath {
return dataFilePath;
}
....
#end
Well you could make Constants a singleton. Leave your code how it is and add this method to the .m:
+ (Constants *)sharedConstants
{
static Constants *_sharedConstants = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedConstants = [[self alloc] init];
});
return _sharedConstants;
}
And the method declaration to the .h:
+ (Constants *)sharedConstants;
Then access your variable like this:
[[Constants sharedConstants] SDataFilePath]
That will force an init the first time you access [Constants sharedConstants] (and only the first time). Also, you'll need to change +(NSString *)SDataFilePath to an instance method, not class method:
-(NSString *)SDataFilePath
This cannot be done this way. Any reason why you want this path to be static? You might want to look into setting dataFilePath with a getter, but no setter and instantiating the class as a singleton. That way you can set the path by some internal method and share the instance as a singleton. See here

How to use static variable(BOOL) in Objective C

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.

Objective C - static variables in categories

I do have a little Problem.
Since my UIViewControlles are all named in the same scheme:
MyView1Controller.h
MyView1Controller.m
MyView1.xib
MyView2Controller.h
MyView2Controller.m
MyView2.xib
MyView3Controller.h
MyView3Controller.m
MyView3.xib
I would now prefer to init my UIViewControllers via a factory method.
Therefore I would implement a Cateogry on UIViewController:
static NSString *standardNibFileName;
#interface UIViewController (FactoryInstantiation)
+ (id) standardViewController;
#end
And in MyView1Controller controller I would declare the static nib file name variable:
static NSString *standardNibFileName = #"MyView1";
#implementation MyView1Controller
Then I could instantiate all my UIViewCOntrollers using the method:
#implementation UIViewController (FactoryInstantiation)
+ (id) standardViewController;
{
if(standardNibFileName != nil) {
NSString *className = NSStringFromClass([self class]);
Class classToIntantiate = NSClassFromString(className);
return [[classToIntantiate alloc] initWithNibName:className bundle:nil];
}
return nil;
}
#end
Init:
MyView1Controller *a = [MyView1Controller standardViewController];
But the static variable is always nil.
Any suggestions on how to solve this issue?
I would appreciate any help!
Thanks in advance.
You can declare a + method instead on UIViewController class and override on the implementing classes
+ (NSString*) getStandardNibFileName {
return #"nibName"
}
Edit: If the implementing class has the same nibName as the base you don't have to override the function.
You have static NSString *standardNibFileName; in .h file as well, give a try removing it, I hope
static NSString *standardNibFileName = #"MyView1"; .m is more than enough

Custom Object Initialization in Objective-C

I created a custom object in Objective-C. Now I want to create a custom initializer. The object has two properties, name and score. So my initializer is as follows:
- (id)initWithName:(NSString *)playerName {
if ((self = [super init])) {
self.name = [playerName retain];
self.score = [NSNumber numberWithInt:0];
}
return self;
}
Am I using retain here properly? Or can I just make it something like self.name = playerName;?
Furthermore, assume I want another initializer, but keep the initWithName:playerName the designated initializer. How would I make the second initializer call the first?
And for the last question, I know I need to override the - (id)init method too. However, what do I do there? Just assign test properties incase the class was initialized with init only?
Thank you!
Am I using retain here properly?
No you are not. You should either use
self.name = playerName;
as you suggested, or (as recommended by Apple)
name = [playerName copy];
It is not recommended to use accessors in -init because subclasses might override them.
Also, note that as NSString implements NSCopying you should use a copy property, not a retain property.
Furthermore, assume I want another initializer, but keep the initWithName:playerName the designated initializer. How would I make the second initializer call the first?
Using -init as an example (because you must override the super class's designated initialiser if your designated initialiser is not the same)
-(id) init
{
return [self initWithName: #"Some default value"];
}
you could keep self.name = playerName; if you have declared name as retained property in .h class and have also #synthesized in .m file.
For the initialization you could put the belwo two line of code in separate method.
-(void) initializeWithName:(NSString*) aName withNumber:(int) aNumber
{
self.name = aName;
self.score = [NSNumber numberWithInt:aNumber];
}
Lets you have three Initialization method.
- (id)initWithName:(NSString *)playerName {
if ((self = [super init])) {
[self initializeWithName:playerName withNumber:0]
}
return self;
}
- (id)initWithNumber:(int*) aNumber {
if ((self = [super init])) {
[self initializeWithName:nil withNumber:aNumber]
}
return self;
}
- (id)init{
if ((self = [super init])) {
[self initializeWithName:nil withNumber:0]
}
return self;
}
For what's it's worth to the rest of us newbies:
In normal languages, can simply define arguments when instantiating the class:
public final class MakeBed {
private var foo:Object;
public var bar:Array;
public function MakeBed(_foo:Object, _bar:Array) {
// Do stuff
foo = _foo;
bar = _bar;
}
}
Then when we want to instantiate the class it's as simple as:
var myBeadMaker:MakeBed = new MakeBed({}, []);
In objc everything is backasswards.
You can create your custom initializer similar to:
// These #properties go into the header.h file
#property (nonatomic, retain) NSString *foo;
#property (nonatomic, retain) NSString *bar;
// This is in your implimentation.m file
- (id) initWithInfo:(NSObject*)foo withBar:(NSArray *)bar {
_foo = foo;
_bar = bar;
}
Objc automatically "synthesizes" the getters and setters and automatically creates a new variable "blindly" using the same _name _but _with _an _underscore in front when you do the #property thing -- it's magic -- bordering on the "almost too helpful" side of things.
Handy for non-newbies, but incredibly confusing for newbies -- just believe that the getter and setter is made and that a _new _var _is _available.
And the clincher that everyone forgets to mention...
When you want to instantiate the class with your custom initializer you do this:
MakeBed myBedMaker = [[MakeBed alloc] initWithInfo:*foo withBar:*bar];

External variable not updating

i'm trying to set the value of a boolean. I can set it successfully, however, in another class, the changes reflected don't show up.
Here's an example:
File1:
#implementation ClassOne //UIViewController
extern BOOL theValue;
- (void)loadFile {
theValue = YES;
}
...
#end
File2:
#implementation ClassTwo //UIViewController
BOOL theValue;
- (void)switchValueChanged {
theValue = NO;
}
#end
I initally set the value in class one, with the initial value of YES. However, when I set the value in ClassTwo to equal NO and return back to ClassOne, the value is still YES.
I'm a little bit stuck. You would think it would update. But it doesn't.
Any help appreciated.
Easiest way to accomplish what you are after is to declare the BOOL in your appDelegate's interface file:
#interface AppDelegate : ....
{
BOOL theValue;
}
#property BOOL theValue;
Then from ClassOne or ClassTwo you can get/set the variable directly by:
MyAppDelegate *appDelegate = (MyAppDelegate * )[[UIApplication sharedApplication] delegate];
appDelegate.theValue = YES;
OR
If you really want to access it globally, simply declare the variable outside your #interface ... #end block
BOOL theValue
#interface AppDelegate : ...
{
...
}
And then you can access the variable theValue from anywhere in your code by simply importing the AppDelegate header file:
#import "AppDelegate.h"
#implementation ClassOne : ....
...
theValue = YES;
I figured it out. When my app launches, it sets theValue to YES by default. Problem was that I was using a viewWillAppear:animated method for this and every time the ClassTwo's view was dismissed the viewWillAppear:animated method was called and the value that was set had been reset. I changed the method to viewDidLoad and everything works fine.
Looks like you're be better off using the Singleton Design Pattern... http://www.galloway.me.uk/tutorials/singleton-classes/