How can I assign values to other class variable in objective-c - objective-c

The below coding is working and I can see the values in my second screen. But I am using the same in other classes with different variables in this format. But it dosent show me the variable if after i type the classname with a dot. I cant figure this out. Is there any way to pass values to other class.
InstallProfiler_2 *installProfiler2 = [[InstallProfiler_2 alloc] initWithNibName:#"InstallProfiler_2" bundle:nil];
installProfiler2.profilerType2 = profilerType;
[self.navigationController pushViewController:installProfiler2 animated:NO];
[installProfiler2 release];

Make sure that:
You have imported the class header.
The #property declarations are in this header and not a class extension.
#property refers to ivars so when you say
if after i type the classname with a dot
this terminology is incorrect, you probably mean after you start typing the name of the variable which has points to an instance of a class.
ClassA.h
#interface ClassA : NSObject
#property (nonatomic, weak) NSInteger myInt;
#end
ClassA.m
#implementation ClassA
#synthesize myInt = _myInt;
#end
ClassB.m
#import "ClassA.h" // <- Import the header of the class
# implementation ClassB
// .. other methods and stuff
- (void)myMethod;
{
ClassA *instanceOfClassA = [[ClassA alloc] init]; // <- Working with an instance not a class
instanceOfClassA.myInt = 1;
}
#end
UPDATE
Make sure your #property () does not have readonly between the round brackets.
Also make sure you have either #synthesize'd the ivar in the implementation or have provided both a getter and a setter for the ivar.
Failing that show some relevant code so we can actually see what your doing - we are answering pretty blindly here.

The dot syntax is only available with property/synthesize

Create a custom setter/getter:
+ (BOOL)awesomeClassVar {
return _classVar;
}
+ (void)setAwesomeClassVar:(BOOL)newVar {
_classVar = newVar;
}
then call as a method from the other class:
BOOL theOtherClassVar = [AwesomeClass awesomeClassVar];
[AwesomeClass setAwesomeClassVar:!theOtherClassVar];

Related

What is the proper way to declare a global variable in Objective-C

So, I was wondering what the proper way to declare a global variable is in an iOS Project.
I don't want it set as a property, because the variable should not be accessible from outside the class.
I am going to provide a few ways I have seen, let me know which is the proper way, and if there is another way that is better.
This way I add the global variable inside curly braces after the #interface declaration in the implementation file .m. Then I can initialize the variable in the viewDidLoad
#import "ViewController.h"
#interface ViewController () {
int globalVariableTest;
}
#end
#implementation ViewController
Another way I add the global variable inside curly braces after the #implementation declaration in the implementation file .m. Again intializing in the viewDidLoad
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController {
int globalVariableTest;
}
Another way is adding the variable after the #implementation without the curly braces, also this allows me to set the intial value without the viewDidLoad
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
int globalVariableTest = 1;
Another way is to add the variable after the #interface inside the header file .h
#interface ViewController : UIViewController
{
int globalVariableTest;
}
So if there is a better way please let me know, all help will be appreciated!
Declaring variables inside curly braces is actually declaring an instance variable or "ivar" for short. That is, a variable that's local to instances of your class.
This used to only be possible after #interface declarations, which is why you sometimes see it there. This changed around Xcode 4 so that you can now do it after #implementation also. As far as I'm aware, this is just stylistic preference. ivars are never accessible outside a class (in theory. Technically, everything is accessible to everything in C), so defining them in the .h won't make them public. It does expose an implementation detail, though, which is why most code I see now that uses them puts them in the #implementation.
But I don't see them much in code anymore. Because when you define a #property what is actually happening under the covers is an ivar, a getter method, and a setter method are all actually being synthesized for you. The getter and setter methods just get the value of the ivar and set the value of the ivar, respectively.
So if what you want is something that has the same scope as a property, but doesn't come with the -myVar and -setMyVar: methods, then this is the right way to go.
But you probably shouldn't want that. There are a whole bunch of reasons that it's nice to only access ivars through accessor methods. It lets you override functionality, translate values, and all the other sorts of fun things abstraction affords you.
If what you want is a #property that isn't accessible outside the class, just declare it in a class extension:
//In MyClass.m
#interface MyClass()
#property NSNumber *myProperty;
#end
#implementation MyClass
//All your implementation stuff here.
#end
Because it's not in the .h file, it won't be "visible" to other classes (In theory. See above about everything being visible in C).
If on the other hand, what you really truly want is something that is really truly global (hint: you shouldn't. Global variables are generally a smell of bad design), you need to define it at the top of your file outside any #interface or #implementation blocks.
Another related tidbit: To define a "global" variable with a scope limited to a given file, look into C's static keyword. It's interesting.
You can use a singleton class to create/share (read / write) all variables across different classes (view controller).
.h
#interface SharedVariables : NSObject {
NSDictionary *dicti_StackSites;
NSDictionary *dicti_UserMe;
}
#property(nonatomic, strong) NSDictionary *dicti_StackSites;
#property(nonatomic, strong) NSDictionary *dicti_UserMe;
+(id)sharedVariablesManager;
#end
SharedVariables.m
#import "SharedVariables.h"
#implementation SharedVariables
#synthesize dicti_StackSites;
#synthesize dicti_UserMe;
+(id)sharedVariablesManager {
static SharedVariables *sharedVariablesClass = nil;
#synchronized(self) {
if (sharedVariablesClass == nil) {
sharedVariablesClass = [[self alloc] init];
}
}
return sharedVariablesClass;
}
-(id)init {
if (self = [super init]) {
dicti_StackSites = [[NSDictionary alloc] init];
dicti_UserMe = [[NSDictionary alloc] init];
}
return self;
}
-(void)dealloc {
}
#end
Usage from any other class
#import "SharedVariables.h"
SharedVariables *sharedManager = [SharedVariables sharedVariablesManager];
//to get sharedManager.dicti_StackSites
//to set sharedManager.dicti_StackSites = ...

Declaring instance variables in iOS - Objective-C

Ok, I've read a lot around these days about this topic and I alwyas get confused because the answers is different every search I make.
I need to know the best way to declare instance variables in iOS. So far I know I should only declare them inside .m file and leave .h clean. But I can't do it: the compiler gives me compilation erros.
Here is some code from .m only.
#interface UIDesign ()
// .m file
{
NSString *test2 = #"test2";
}
#property (nonatomic, assign) int privateInt;
#end
#implementation UIDesign
{
NSString *test1 = #"test1";
}
Both strings are declared incorrectly and I don't know why. The compiler says: expected ';' at end of declaration list.
So the question is: how can I declare instance variables? I will only need them inside the class.
You cannot initialize instance variables. They are all initialized to nil or zeroes. So compiler expect a semicolon when you are writing an equal sign.
You can initialize them in init method.
You are attempting to add an instance variable to a class extension or category which is unsupported. [EDIT 2013-05-12 06-11-08: ivars in class extension are supported, but not in categories.] As an alternative:
#interface UIDesign : NSObject
#end
#interface UIDesign ()
#property (nonatomic, assign) int privateInt;
#end
#implementation UIDesign
#synthesize privateInt = _privateInt;
- (void)someMethod {
self.privateInt = 42;
}
#end
On the other hand, if you just want to declare an instance variable inside the implementation, just do it there:
#implementation UIDesign {
int _privateInt;
}
#end
EDIT: just noticed that you're also attempting to initialize instance variables in the declaration which is also unsupported. So:
#interface UIDesign : NSObject
#end
#implementation UIDesign {
NSString *_test;
}
- (id)init {
self = [super init];
if( !self ) return nil;
_test = #"Foo";
return self;
}
#end

About moving few methods to the superclass

I need to move the same method from 4 different classes to the superclass.
Such methods are exactly the same except for the type of a variable declared in them:
For example, in the method in the first class I have
FirstClass var = [[FirstClass alloc] init]
in the second class
SecondClass var = [[SecondClass alloc] init]
and so on.
What's the best way to implement this variation in the superclass ?
Should I use NSClassFromString in the superclass and get each string from each method in the subclasses?
thanks
I'm not 100% sure I get what you mean. So I could be answering the wrong question
If inside your class you need to use an object (I've called it worker below) to do your work, but the class of this object is not known til later, you can use dependency injection (DI).
MyClass.h
#interface MyClass : NSObject
#property (nonatomic, retain) id<WorkerInterface> worker;
#end
MyClass.m
#implementation MyClass
#synthesize worker = _worker;
- (void)myMethod;
{
[self.worker doSomething];
}
// You could also provide a default class to use if one is not passed in
//
// - (id<WorkerInterface)worker;
// {
// if (!_worker) {
// _worker = [[DefaultWorker alloc] init];
// }
// return _worker;
// }
#end
Now whenever I instantiate this class I can simply pass in the appropriate object to be used e.g:
MyWorkerClass *worker = [[MyWorkerClass alloc] init]; // <- Conforms to #protocol(WorkerInterface)
MyClass *instance = [[MyClass alloc] init];
instance.worker = worker;
[instance doSomething];
If all the different types of iVar's you intend on initializing in the subclasses are descended from a common class, then I'd store that class in the super, or else just store it as an id. Then, setup a property accessor in each of your subclasses the casts the iVar as you need it.
#interface superClass : NSObject{
id _superIvar;
}
#end
#implementation superClass : NSObject
....super's code....
#end
Now in the implementation of the subclass declare a property in a category, shown below (or in the interface, if you want it public)
#interface subClass (private)
#property (strong) ClassType *superIvar;
#end;
#implementation
- (void) setSuperIvar:(ClassType *)superIvar{
_superIvar = superIvar;
}
- (ClassType *) superIvar{
return (ClassType *) _superIvar;
}
- (void) someMethodThatUsesSuperIvar{
[self.superIvar doSomething];
}
#end
Alternatively, if you don't want to open your _superIvar to direct access, you can set a property on the superclass and access through the property on the subclass. But in this way you can easily access super's ivars cast to the appropriate type.

Question about class member declarations

I`m new to the Objective-C world, so I have a couple of questions about class member declarations. Please notice the comments in the code below:
In header file I have code such
#interface MyClass : NSObject {
//what we points here ? Object or something else ?
NSString *myString;
}
// In interface we declare NSTring *myString in #property declaration is (NSString *) myString.
// What is the difference here ? Why we don`t use the same declaration as above ?
#property(nonatomic, retain) (NSString *) myString;
#end
The thing you're missing is that instance variables (defined between curly braces) are not accessed from the outside (i.e. other objects). To do that - you have to define a property for the instance var (by using #property keyword) to know how outside objects can access a value of given instance var. Also in implementation file (.m) you have to #synthesize instance variable accessor methods for it's appropriate property. Please note that #property declaration not only defines what it holds (NSString *myString), but also how it's being accessed and set. You can define property as read only (#property (readonly)...) or accessible from few threads at a time (#property (nonatomic)).
Also - if your instance var is named differently from the property it represents to other objects - you must show that in implementation file (#synthesize propertyName=instanveVariableName)
update
MyClass *myInstance = [[MyClass alloc] init];
[myInstance myString]; // returns myString property
Try running above 2 lines of code without #property and you'll see the difference.
Actually you are defining a Property of yar class.#interface MyClass : NSObject {
//public object
#public
NSString *myString;
//private object
NSString *myString2;
}
class structure for obj-c
.h file
#interface MyClass : NSObject {
//Your member variable;
// you member objects;
}
//property declarations
//function declarations
#end
so it should look like
#interface MyClass : NSObject {
NSString *str;
}
#property(nanatomic,retain) NSString *str;
-(void)method;
#end

How can I access variables from another class?

There is probably a very simple solution for this but I can't get it working.
I have got multiple classes in my Cocoa file. In one of the classes class1 I create a variable that I need to use in another class class2 as well. Is there a simple way to import this variable in class2?
You can either make the variable public, or make it into a property. For example, to make it public:
#interface Class1
{
#public
int var;
}
// methods...
#end
// Inside a Class2 method:
Class1 *obj = ...;
obj->var = 3;
To make it a property:
#interface Class1
{
int var; // #protected by default
}
#property (readwrite, nonatomic) int var;
// methods...
#end
#implementation Class1
#synthesize var;
...
#end
// Inside a Class2 method:
Class1 *obj = ...;
obj.var = 3; // implicitly calls [obj setVar:3]
int x = obj.var; // implicitly calls x = [obj var];
You could expose the variable in class2 as a property. If class1 has a reference to class2, class1 can then see the variable. Honestly, though, it sounds like you're a beginner to both Objective-C and object oriented programming. I recommend you read up more on both.
Here is a place to start for object oriented programming with Objective-C.
try making a file that holds your variables that need to be accessed throughout the app.
extern NSString *stringVariable;
#interface GlobalVariables
#property (retain, nonatomic) NSString *stringVariable;
#end
and in the GlobalVariables.m file add
#import "GlobalVariables.h"
#implements GlobalVariables
#synthesize stringVariable;
NSString *stringVariable;
#end
And then as long as you import GlobalVariables.h into which ever .m files you need to access that variable in you can assign and access anywhere throughout your program.
EDIT
My answer that I have given above is differently not the way I would go about doing this now.
It would be more like
#interface MyClass
#property (nonatomic, strong) NSString *myVariable;
#end
then in the .m file
#implementation MyClass
#sythesize = myVariable = _myVariable; // Not that we need to do this anymore
#end
Then in another class in some method I would have
// .....
MyClass *myClass = [[MyClass alloc] init];
[myClass setMyVariable:#"My String to go in my variable"];
// .....
In "XCode" you need to make import, create object by declaring it as the property, and then use "object.variable" syntax. The file "Class2.m" would look in the following way:
#import Class2.h
#import Class1.h;
#interface Class2 ()
...
#property (nonatomic, strong) Class1 *class1;
...
#end
#implementation Class2
//accessing the variable from balloon.h
...class1.variableFromClass1...;
...
#end
Thanks! :-)