Accessing variables of another class in xcode - ios

I have a balloonGameViewController.h and another class I made called balloon.h
I want to access some variables I set in balloon.h from the viewController
Is there any way I can achieve this?

How are your variables set in ballon.h? You should use #property to declare variables that you want other classes to be able to access. Then, you can access them either by treating them as a method, or dot notation:
myObject.variable;
myObject should be an instance of type balloon, which can be created by importing the balloon.h and initializing a new instance, if you do not already have one.

Just import the balloon.h file into your balloonGameViewController
#import balloon.h
and then access the variables as usual, assuming they are public. Otherwise you have to make them public or create getters and setters.

As others said, you'll have to #import baloon.h. But you did not say if these variables are global variables or ivars of a class. If they are ivars, you'll first have to find the instance of the class (the object) of which they are ivars. If you have that, and they are public or properties, you can access them as members of that object.
IOW, it is hard to tell if you don't tell us what kind of variables in balloon.h you want to access. But, see above.

i don't know if i got your question well, but i faced that once upon a time , i couldn't access the variables via (.) operator but via (->)
in my case there were 2 classes : MenuCalss , and ToolsClass ;
in ToolsClass.h :
#public
bool ToolBarVisible;
//in MenuCalss there was a ToolsClassObject.
ToolsClassObject is an instance of type ToolsClass, which can be created by importing the ToolsClass.h and initializing a new instance.
, and the access way
in MenuClass.m is :
ToolsClassObject->ToolBarVisible = false;

Using your XCode you need to make import, declare the property, and then use "object.variable" syntax. The file "balloonGameViewController.m" would look in the following way:
#import balloonGameViewController.h
#import balloon.h;
#interface balloonGameViewController ()
...
#property (nonatomic, strong) balloon *objectBalloon;
...
#end
#implementation balloonGameViewController
//accessing the variable from balloon.h
...objectBalloon.variableFromBalloon...;
...
#end

Related

Objective-C member variable vs property in source file

I understand the difference between member variable and property in Object-C, but there is one thing make me confused. See the following code.
test.h
#interface test : NSObject
#end
test.m
#interface test()
{
NSString *memberStr;
}
#property (nonatomic, strong) NSString *properyStr;
#end
As showed, the memberStr and propertyStr can't be see by outside. I want to know what is the difference between them. Because I don't how to chose the solution when i want to use local variable.
Thanks!
properyStr will have the getters and setters generated automatically.
you can define custom setter for propertyStr as below. When you use self.propertyStr, it will create a default object for you. It will be useful for initialising objects like NSMutableArray, NSMutableDictionary etc.
- (NSString *)properyStr
{
if(_propertyStr == nil)
{
_propertyStr = #"";
}
return _propertyStr;
}
memberStr will not have these options.
I understand the difference between member variable and property in Object-C
I'm not sure that you do.
A member variable is a variable that's visible only within the scope of instance methods.
A property is some attribute of the class that can be set or get. The compiler will write appropriate getters and, optionally, setters, and will organise storage for itself, unless you override any of those things.
Both member variables and properties can be declared either in the #implementation or in the #interface.
A member variable can never be accessed directly by unrelated classes, regardless of where it was declared. If it's in the #interface then it can be accessed by subclasses.
A property can always be read and, optionally, written by any other class, regardless of where it was declared. External classes can use the key-value coding mechanism even if the #property isn't visible to them.
Questions you may therefore be likely to ask:
Q) Why would I put a member variable into the #interface?
A) It's unlikely you would. It will expose it to subclasses but usually wanting to do so is a design flaw. However, in olden times you had to put all member variables into the #interface for reasons of how the old Objective-C runtime worked. So older code and stuck-in-their-ways programmers will still sometimes follow this pattern.
Q) Why would I declare a property visible only to the #implementation?
A) It's unlikely you would. However in olden times this was the only way to create member variables that weren't visible in the #interface so was the way people did most member variables for a brief period. Similarly, you could declare something, say retain, then use the getter/setter and assume correct memory management was going on, so it acted as some syntactic sugar in the days before ARC was introduced. As with the previous answer, there are therefore some people who still do so through habit and some code that still does so on account of being older. It's not something you'd often do nowadays.
EDIT: a better summary: properties adjust your class interface. Member variables adjust its implementation. In object-oriented programming you should be thinking of the two things as entirely disjoint.
One of the main purposes of object-oriented programming is to have a bunch of discrete actors that say "I can do X" with exactly how they do it being nobody else's business.
A property says what a class can do. A member variable is for the benefit of how the class does it.
Semantically they're completely separate issues.
First of memberStr is an instance variable or ivar.
There is no need to have memberStr any more if you have a property setup for this all you need is.
#interface test()
#property (nonatomic, strong) NSString *properyStr;
#end
The reason for this is that the ivar will be automatically created for you along side the setter and getter methods.
The only difference between declaring the property in the implementation files (.m) interface over the interface file (.h) is that it will be private to this class only. There are many advantages for having this such as maybe you don't want anything outside of the class to know about it but you want the property to be in scope for this class still. One thing that they are used for in this manner is when you have a readonly property declared public but you still want the setter to be in scope for this class. So you may have something like
.h
#interface MyObject : NSObject
// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
#property (nonatomic, readonly) NSString *firstName;
#end
.m
#interface MyObject()
// But we still want to use the setter for this class only.
#property (nonatomic, strong) NSString *firstName;
#end
Otherwise except for being private to that class only; having the property in the implementation file (.m) will be the exact same as having it in the interface file (.h) they will act and do the same thing.

Difference between declaring instance variable in .h file and .m inside the #interface braces

If some one can brief on declaring instance variable inside .h file inside #interface braces and in .m file #interface braces. like this below
#interface ViewController : UIViewController { NSString *str ; }
#interface ViewController () { NSString *anotherStr ; }
Thx
There's even a third place where you can define instance variables: at the implementation statement:
#implementation ViewController { NSString *yetAnotherString; }
AFAIK, in the olden times you could only define the instance variables in the main interface. The other two places were added later. You can also mix them (as long as they have different names).
The advantage of defining the variables at #implementation and also the class extensions #interface ViewController () level (when done inside an .m file) is that you can hide implementation details from users of your API. In other words, if someone reads the .h file (s)he doesn't know about the variables. This makes the visible API cleaner and is also a concept called "information hiding" which is quite important in object oriented programming: don't expose too much implementation details so you can change the implementation without breaking code using the class.
Note that you can also define IBOutlet variables at all three levels and Interface Builder will detect and use them!
So when you're deciding where to define the variable you can simply ask yourself: Do other people need to see the variable when they see the .h file? IMHO this is only true when you need/want to make a variable #public. For all other cases, you can define them at the class extension or implementation level to make the API cleaner.
Whatever you declare in ViewControllerA.H is public. It means that other view controllers that contain the ViewControllerA object can access use the methods or variables directly. Whatever you declare in .M is private, other view controller can not access it immediately.
As for my own practice, most of the variable (I don't use much) or properties I declare in .M to prevent other view controller to access it directly. It is just like one concept in Object Oriented Programming - Data Encapsulation.
Note: Please be reminded that this should not be confused with #public, #protected, #private like DarkDust mentioned below. It will be another different topic.
In objective-C while you declare the member in .h file, it becomes visible to the other file when .h file is imported as header.
By default all member variables are private. So, user can not use them directly. But with methods of runtime.h and setValueForKey give them an alternate way to set those variable.
To avoid the user to do such mischief, its advisable to declare your private variables in .m file. They are called extensions as well.
For example you have created a variable in your appdelegate file. Now import appdelegate.h file to other .m file. Get the instance of appdelegate by sharedApplication delegate. Now you can set value by below way.
[appdelegate setValue:your_value forKey:#"name of variable"];
Though it was private, user could do so. Its because when you check for auto suggestion window, it will list down your private variable with strike through. To avoid getting those variable inside this window, it is advisable to declare them in .m file.

iOS Basics: private property, public setter/getter

I've been reading the tutorials and I'm right now designing the model's architecture, and since I'm new to Objective-C, I'm not sure if the standards are like Java where you have public setter/getter and private attribute. This is 1 question I'd like to ask.
If the standards are so, declaring private properties are done in the *.m file #interface, but how do I #syntetize a setter/getter and how do I call them from outside: is it like [object SetProperty:property] ?
If the standards are different, can I get an example of a model class?
Thanks in advance.
A property is essentially a promise that a class provides certain accessor methods. For example:
#property(strong, nonatomic) Foo *foo;
is a promise that the class provides -foo and -setFoo: methods. So, if you want the accessors to be public, declare the property in your class's public interface (i.e. in the header file) and be done with it.
It's true that the instance variable that backs that property (_foo, unless you specify a different name) will then be accessible, but it's very poor form to access another object's instance variables directly. Many things in Objective-C are governed by convention and that's generally enough to avoid problems. Also, a given property doesn't have to be backed by any instance variable at all: a property like fullName might be computed from other properties like firstName and lastName, so there's good reason beyond mere convention for clients to avoid accessing ivars directly.
The common approach if you want to give access to your attribute is to use the keyword #property in the .h file of your class to define a property. This will automatically define a setter and a getter and you don't need to synthesise your property as of Xcode 4.4.
Your private attribute will be accessible within your .m file and will have the name of your property with "_" as a prefix by default.
You can create a private property and create public setter/getter method of your own. From this method you can assign or retrieve the value back.
#interface Person : NSObject
-(void)setTheName:(NSString *)fullName;
-(NSString *)theName;
#end
Implementation file:
#import "Person.h"
#interface Person()
#property(atomic) NSString *fullName;
#end
#implementation Person
-(void)setTheName:(NSString *)fullName{
self.fullName = fullName;
}
-(NSString *)theName{
return self.fullName;
}
#end
In the above is private however you can check the selector still exists(but throws a warning)
if ([p respondsToSelector:#selector(setFullName:)]) {
[p performSelector:#selector(setFullName:) withObject:#"Anoop"];
}
NSLog(#">>>> %#",[p theName]);
Output will be :
>>>> Anoop
However it is seldom required to set any private property from outside. If that is the requirement we can make the property public.
Well it is true that Objective-C uses another terminology than most of the other languages like Java. If I get what you're asking, if you want a property to be directly available outside the class, the property must be declared in the .h file. However if you want to hide the implementation of your code, you can declare a property in the .m file and provide setters/getters to the outside world just returning the information you want to be visible.
The #synthesize clause is to me a simpifier. By synthesizing a property the getter/setter will be automatically implemented and you don't need to do it yourself.
Does this answer your question ?
Understand that declaring a property causes the compiler to create accessor for you . so if i require a pseudo private property personally I declare it in the implementation, if i need pseudo public property i declare it in the header. public getter / private setter can be handled as indicated below. There is no need to create your own setters and getters prefer using an attribute as it saves writing setters/getters ;
in the header (.h)
#interface Person : NSObject
#property (nonatomic, readonly) NSString *fullName;
#end
in the implementation file (.m)
#import "Person.h"
#interface Person()
#property (nonatomic, readwrite) NSString *fullName;
#end
#implementation Person
... whatever this class does
// self.fullName = #"John Doe";
#end

(Objective C) Do methods and variables need to be declared in head file(.h) if it is only used in its own class?

I have reviewed many code samples and have found that people commonly declare all methods and global variables in the header (.h) file. Is it necessary?
Methods to be used publicly (i.e. by classes other than the class implementing the method) and (truly) global variables should indeed be declared in the header file. The whole point is that you can import the header file in another source code file to gain access to the functionality declared there.
Methods that are meant to be private -- that is only to be called as part of the internal implementation of a class -- can be declared in a class extension. With recent versions of LLVM/Xcode, you actually don't even need to do that for non-#property methods. You can simply implement them and the compiler will be smart enough to see that they're there when called from other methods in the same class's implementation.
If you need to explicitly define a private ivar (rare these days), you can do so in a brace-enclosed section immediately after #implementation or #interface ClassName ().
In short: declare methods, functions, and variables that need be accessible from other classes in the .h file. Private methods and variable should be kept private by declaring them only in the .m file.
In recent versions of the SDK, you don’t have to declare methods that you only use internally to the class, so that can cut down clutter in your .h file. In general, the only methods, properties, and ivars that I put in my .h are the ones that I know other classes will need access to. That way, I never make the mistake of externally accessing a property that is supposed to be internal-only. The rest, I put in a class extension in the .m file like this:
#import "MyClass.h"
#interface MyClass ()
{
int _myIvar; // I rarely use these anymore,
// but if you want to use them, they go here.
}
#property (strong, nonatomic) NSArray *someArray;
#property (strong, nonatomic) NSDictionary *anotherProperty
#end
#implementation MyClass
#end
Header files have no special significance at all to the compiler. The preprocessor just copy-pastes them into the implementation file when you write #import anyway.

Declaring variables in .h file

Just wondering if its good programing practice to have a lot of variables declared in the .h file.
I'm writing my first app through which im learning xcode and obj-c. This ios app has just one xib, one .m and one .h file. I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just end up declaring it in the .h file which seems like im making the variable global which i dont think is a good idea to have a lot of those.
Is this safe/ok to have a lot of variables declared in .h file or should i approach it in some other way?
Thanks
Is this safe/ok to have a lot of variables declared in .h file or
should i approach it in some other way?
It's absolutely OK to include a lot of variables in the .h! It just increases compile time a little and increases the size of your binary by an arbitrary amount. If it worries you, just split your implementation across a couple of categories.
I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just
end up declaring it in the .h file which seems like im making the
variable global which i dont think is a good idea to have a lot of
those.
Variables that are accessed outside of one method should always be declared as iVars, and as properties if they require strong reference, or need to be accessed by outside classes. Global variables are way different, and you needn't worry about it.
Your .h file is the public interface of your class. It should only contain properties and methods that other classes need to know about.
You can declare ivars and internal methods and properties in a class continuation in the .m file (this is so common that one is now automatically included in the template for UIViewController subclasses).
You can also declare ivars within braces directly after the #implementation.
In iOS5, with ARC, declared ivars are strong references by default, so you don't have to use properties or accessor methods, but that choice depends on the rest of your class. For example, you may use lazy instantiation or perform other tasks or KVO when getting or setting a variable, in which case you'd always want to access it via a property or method, and if you're doing that for some ivars, and not others, it starts to look a bit messy.
It is alright for you to have many variables declared in the interface in the .h file when needed (as touched on by the other answers). But it would be wise for you to consider moving instance variables that do not need to be public into a category in the .m file. For example:
In the .h:
#import <Foundation/Foundation.h>
#interface SomeClass : NSObject {
NSDictionary *publicDict;
NSArray *privateArray;
}
#property (nonatomic, strong) NSDictionary *publicDict;
-(void)publicMethod:(id)anObj;
#end
And in the .m file:
#import "SomeClass.h"
#interface SomeClass () //Category that denotes private methods
#property (nonatomic, strong) NSArray *privateArray;
-(void)privateMethod;
#end
#implementation
#synthesize publicDict;
#synthesize privateArray;
-(id)init {
//...
}
-(void)publicMethod:(id)anObj {
//..
}
-(void)privateMethod {
//..
}
#end
This causes the compiler to issue a warning whenever any of the private methods contained in that category are accessed by outside classes. Additionally, this is the widely accepted way of adhering to an aspect of encapsulation in Objective-C.

Resources