Understanding private instance variable - objective-c

I'm having a hard time understanding private instance variables through example. After reading about private instance variables, I went to Xcode and tried to verify how they work.
In the book I'm reading, it states that if you declare an instance variable in the implementation file of a superclass, the instance variable will be private and inaccessible to subclasses.
I tried proving it doing the following without any luck.
/** SuperClass interface file**/
#import <Foundation/Foundation.h>
#interface ClassA : NSObject
-(void) setX;
-(void) printX;
#end
/**SuperClass implementation file **/
#import "ClassA.h"
#implementation ClassA
{
int x;
}
-(void) setX
{
x = 100;
}
-(void) printX
{
NSLog(#" x is equal to %i", x);
}
#end
/** interface file of subclass **/
#import "ClassA.h"
#interface ClassB : ClassA
#end
/**Main file **/
#import "ClassA.h"
#import "ClassB.h"
int main(int argc, const char * argv[])
{
#autoreleasepool
{
ClassA * a;
a = [[ClassA alloc] init];
ClassB * b;
b = [[ClassB alloc] init];
[b setX];
[b printX];
}
return 0;
}
The program prints the following:
x is equal to 100
isn't "x" a private instance variable and inaccessible by object "b", because "x" is declared in the implementation file of superClass "a" while "b" is a subclass?
The books says "instance variables that are to be accessed directly by a subclass must be declared in the interface section and not in the implementation section...Instance variables declared or synthesized in the implementation section are private instance variables and are not directly accessible by subclasses."
Really confused by this.

The methods setX and printX are public and visible and thus can be called on the instance of ClassB. Since they are public they can also be called by the ClassB, like this.
#implementation ClassB
- (void)fig {
[self setX];
}
#end
What can't be done is for ClassB to directly access the value x. Like this:
#implementation ClassB
- (void)foo {
NSLog(#"x is now %i", x);
}
#end
ClassB does not have direct access to x, but it has indirect access to x through the superclass methods. This indirect access is an object oriented programming concept known as encapsulation.

Ivars have #protected attribute by default, means subclasses can access them. To declare ivar as private, use #private attribute before ivar declaration:
#interface ClassA : NSObject
{
#private
int x;
}
If you declare your ivars in #implementation section, the only way for them to be visible to subclasses is to import .m file in your subclass, but your can't use them because they're private.
Or don't use ivars at all, since Objective-C properties now create ivars automatically. If you need a private property, you can declare it via anonymous category in .m file like this:
#interface MyClass ()
#property (nonatomic) NSInteger x;
#end
UPDATE:
I think I understand what's confusing you. Public and protected ivars are inherited by subclasses and can be accessed directly as instance variables of subclass, no need to use accessor methods from a subclass.

Related

What is the difference between the areas where you can declare instance variables in Objective-C? [duplicate]

Ever since starting to work on iOS apps and objective C I've been really puzzled by the different locations where one could be declaring and defining variables. On one hand we have the traditional C approach, on the other we have the new ObjectiveC directives that add OO on top of that. Could you folks helps me understand the best practice and situations where I'd want to use these locations for my variables and perhaps correct my present understanding?
Here's a sample class (.h and .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
#end
and
#import "SampleClass.h"
// 4) what goes here?
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
#implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
#end
My understanding of 1 and 4 is that those are C-style file-based declarations and definitions that have no understanding whatsoever of the concept of class, and thus have to be used exactly how they would be used in C. I've seen them used for implementing static variable-based singletons before. Are there other convenient uses I'm missing?
My take from working with iOS is that ivars have been alost completely phased out outside of the #synthesize directive and thus can be mostly ignored. Is that the case?
Regarding 5: why would I ever want to declare methods in private interfaces? My private class methods seem to compile just fine without a declaration in the interface. Is it mostly for readability?
Thanks a bunch, folks!
I can understand your confusion. Especially since recent updates to Xcode and the new LLVM compiler changed the way ivars and properties can be declared.
Before "modern" Objective-C (in "old" Obj-C 2.0) you didn't have a lot of choices. Instance variables used to be declared in the header between the curly brackets { }:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#end
You were able to access these variables only in your implementation, but not from other classes. To do that, you had to declare accessor methods, that look something like this:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
- (int)myVar;
- (void)setMyVar:(int)newVar;
#end
// MyClass.m
#implementation MyClass
- (int)myVar {
return myVar;
}
- (void)setMyVar:(int)newVar {
if (newVar != myVar) {
myVar = newVar;
}
}
#end
This way you were able to get and set this instance variable from other classes too, using the usual square bracket syntax to send messages (call methods):
// OtherClass.m
int v = [myClass myVar]; // assuming myClass is an object of type MyClass.
[myClass setMyVar:v+1];
Because manually declaring and implementing every accessor method was quite annoying, #property and #synthesize were introduced to automatically generate the accessor methods:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#synthesize myVar;
#end
The result is much clearer and shorter code. The accessor methods will be implemented for you and you can still use the bracket syntax as before. But in addition, you can also use the dot syntax to access properties:
// OtherClass.m
int v = myClass.myVar; // assuming myClass is an object of type MyClass.
myClass.myVar = v+1;
Since Xcode 4.4 you don't have to declare an instance variable yourself anymore and you can skip #synthesize too. If you don't declare an ivar, the compiler will add it for you and it will also generate the accessor methods without you having to use #synthesize.
The default name for the automatically generated ivar is the name or your property starting with an underscore. You can change the generated ivar's name by using #synthesize myVar = iVarName;
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#end
This will work exactly as the code above. For compatibility reasons you can still declare ivars in the header. But because the only reason why you would want to do that (and not declare a property) is to create a private variable, you can now do that in the implementation file as well and this is the preferred way.
An #interface block in the implementation file is actually an Extension and can be used to forward declare methods (not needed anymore) and to (re)declare properties. You could for instance declare a readonly property in your header.
#property (nonatomic, readonly) myReadOnlyVar;
and redeclare it in your implementation file as readwrite to be able to set it using the property syntax and not only via direct access to the ivar.
As for declaring variables completely outside of any #interface or #implementation block, yes those are plain C variables and work exactly the same.
First, read #DrummerB's answer. It a good overview of the whys and what you should generally do. With that in mind, to your specific questions:
#import <Foundation/Foundation.h>
// 1) What do I declare here?
No actual variable definitions go here (it's technically legal to do so if you know exactly what you're doing, but never do this). You may define several other kinds of things:
typdefs
enums
externs
Externs look like variable declarations, but they're just a promise to actually declare it somewhere else. In ObjC, they should only be used to declare constants, and generally only string constants. For instance:
extern NSString * const MYSomethingHappenedNotification;
You would then in your .m file declare the actual constant:
NSString * const MYSomethingHappenedNotification = #"MYSomethingHappenedNotification";
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
As noted by DrummerB, this is legacy. Don't put anything here.
// 3) class-specific method / property declarations
#end
Yep.
#import "SampleClass.h"
// 4) what goes here?
External constants, as described above. Also file static variables can go here. These are the equivalent of class variables in other languages.
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
Yep
#implementation SampleClass
{
// 6) define ivars
}
But very rarely. Almost always you should allow clang (Xcode) to create the variables for you. The exceptions are usually around non-ObjC ivars (like Core Foundation objects, and especially C++ objects if this is an ObjC++ class), or ivars that have weird storage semantics (like ivars that don't match with a property for some reason).
// 7) define methods and synthesize properties from both public and private
// interfaces
Generally you shouldn't #synthesize anymore. Clang (Xcode) will do it for you, and you should let it.
Over the last few years, things have gotten dramatically simpler. The side-effect is that there are now three different eras (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). So when you see the older code, it can be a little confusing. Thus confusion arising from simplicity :D
I'm also pretty new, so hopefully I don't screw anything up.
1 & 4: C-style global variables: they have file wide scope. The difference between the two is that, since they're file wide, the first will be available to anyone importing the header while the second is not.
2: instance variables. Most instance variables are synthesized and retrieved/set through accessors using properties because it makes memory management nice and simple, as well as gives you easy-to-understand dot notation.
6: Implementation ivars are somewhat new. It's a good place to put private ivars, since you want to only expose what's needed in the public header, but subclasses don't inherit them AFAIK.
3 & 7: Public method and property declarations, then implementations.
5: Private interface. I always use private interfaces whenever I can to keep things clean and create a kind of black box effect. If they don't need to know about it, put it there. I also do it for readability, don't know if there are any other reasons.
This is an example of all kinds of variables declared in Objective-C. The variable name indicate its access.
File: Animal.h
#interface Animal : NSObject
{
NSObject *iProtected;
#package
NSObject *iPackage;
#private
NSObject *iPrivate;
#protected
NSObject *iProtected2; // default access. Only visible to subclasses.
#public
NSObject *iPublic;
}
#property (nonatomic,strong) NSObject *iPublic2;
#end
File: Animal.m
#import "Animal.h"
// Same behaviour for categories (x) than for class extensions ().
#interface Animal(){
#public
NSString *iNotVisible;
}
#property (nonatomic,strong) NSObject *iNotVisible2;
#end
#implementation Animal {
#public
NSString *iNotVisible3;
}
-(id) init {
self = [super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
iPrivate = #"iPrivate";
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
_iPublic2 = #"iPublic2";
iNotVisible = #"iNotVisible";
_iNotVisible2 = #"iNotVisible2";
iNotVisible3 = #"iNotVisible3";
}
return self;
}
#end
Note that the iNotVisible variables are not visible from any other class. This is a visibility issue, so declaring them with #property or #public doesn't change it.
Inside a constructor it's good practice to access variables declared with #property using underscore instead self to avoid side effects.
Let's try to access the variables.
File: Cow.h
#import "Animal.h"
#interface Cow : Animal
#end
File: Cow.m
#import "Cow.h"
#include <objc/runtime.h>
#implementation Cow
-(id)init {
self=[super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
//iPrivate = #"iPrivate"; // compiler error: variable is private
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
self.iPublic2 = #"iPublic2"; // using self because the backing ivar is private
//iNotVisible = #"iNotVisible"; // compiler error: undeclared identifier
//_iNotVisible2 = #"iNotVisible2"; // compiler error: undeclared identifier
//iNotVisible3 = #"iNotVisible3"; // compiler error: undeclared identifier
}
return self;
}
#end
We can still access the not visible variables using the runtime.
File: Cow.m (part 2)
#implementation Cow(blindAcess)
- (void) setIvar:(NSString*)name value:(id)value {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
object_setIvar(self, ivar, value);
}
- (id) getIvar:(NSString*)name {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
id thing = object_getIvar(self, ivar);
return thing;
}
-(void) blindAccess {
[self setIvar:#"iNotVisible" value:#"iMadeVisible"];
[self setIvar:#"_iNotVisible2" value:#"iMadeVisible2"];
[self setIvar:#"iNotVisible3" value:#"iMadeVisible3"];
NSLog(#"\n%# \n%# \n%#",
[self getIvar:#"iNotVisible"],
[self getIvar:#"_iNotVisible2"],
[self getIvar:#"iNotVisible3"]);
}
#end
Let's try to access the not visible variables.
File: main.m
#import "Cow.h"
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
Cow *cow = [Cow new];
[cow performSelector:#selector(blindAccess)];
}
}
This prints
iMadeVisible
iMadeVisible2
iMadeVisible3
Note that I was able to access the backing ivar _iNotVisible2 which is private to the subclass. In Objective-C all variables can be read or set, even those that are marked #private, no exceptions.
I didn't include associated objects or C variables as they are different birds. As for C variables, any variable defined outside #interface X{} or #implementation X{} is a C variable with file scope and static storage.
I didn't discuss memory management attributes, or readonly/readwrite, getter/setter attributes.

Access private instance variable of parent class

I can't figure out why class B can access class A private instance variable.
Here is my code
A.h
#import <Foundation/Foundation.h>
#interface A : NSObject
{
#private
int x;
}
#property int x;
-(void)printX;
#end
A.m
#import "A.h"
#implementation A
#synthesize x;
-(void)printX
{
NSLog(#"%i", x);
}
#end
B.h
#import "A.h"
#interface B : A
{
}
#end
main.m
B *tr = [[B alloc] init];
tr.x = 10;
[tr printX];
Here I can access instance variable of A class x despite it is declarated as private ?
You are not accessing the private variable there, at least not directly: you are accessing a public property, which has legitimate access to the private ivar.
Your code is equivalent to this:
B *tr = [[B alloc] init];
[tr setX:10];
[tr printX];
The #synthesize statement created the getter and the setter methods for you. If you want only a getter to be available, mark your property readonly, and do all writings through an ivar in the A class.
In your implementation file do this on the top..
#interface A : NSObject
{
#private
int x;
}
#property int x;
#end
this way x will be private since it is in the implementation file. not the interface section...all classes import the interface section of A ..so it's variable are accessible to its subclasses.

Objective-C : How may I hide a class member from outside the class?

I'm fighting with something and I don't find any satisfying solution.
I have a class with a "myMutableArray" member.
I would like the class to manage itself adding and removing items from the array, so I don't want any other class being able to access the member and call NSMutableArray methods on it.
In an ideal situation, I would like to have a private getter (to be able to call self.myMutableArray) and a public setter for this member.
Do you know how I may achieve this ?
In other words :
I would like other classes
be able to call
- [oneInstance setMyMutableArray:thisArray]; // set
- oneInstance.myMutableArray = thisArray; // set using setter
- thisArray = oneInstance.myMutableArray; // get
- [oneInstance addItem:anItem]; // add
not being able to call :
- [oneInstance.myMutableArray add:etc...] // add
I would like my class
be able to call
- self.myMytableArray = [NSMutableArray array]; // set
- thisArray = self.myMytableArray ; // get
Thank you.
Is there any reason you need the public setter? It sounds like the class itself owns the array. You'd probably be better off not providing any public property access to the field, and making a public method which copies the values into your private field.
// public interface, in the .h file
#interface MyClass : // superclass, protocols, etc.
- (void) setSomething:(NSArray *)values;
#end
// private interface, not in the .h
#interface MyClass ()
#property (/* attributes */) NSMutableArray *myMutableArray;
#end
#implementation MyClass
#synthesize myMutableArray = myMutableArray_;
- (void) setSomething:(NSArray *)values
{
[self.myMutableArray setArray:values];
}
#end
Foo.h
#interface Foo : NSObject
#property(readonly, retain) NSArray * myReadonlyArray;
- (void) addItem: (Item *) anItem;
- (BOOL) publiclyDoSomething;
#end
Foo.m
#interface Foo()
#property(readwrite, retain) NSMutableArray * myMutableArray;
- (void) doSomethingInPrivate;
#end
#implementation Foo
#synthesize myMutableArray = myMutableArray_;
- (void) addItem: (Item *) anItem
{
// assuming myMutableArray_ was already iniitialized
[self.myMutableArray addObject: anItem];
}
- (NSArray *)myReadonlyArray
{
return self.myMutableArray;
}
... rest of methods (including the public/private) implementations ...
#end
Some details:
Objective-C has "instance variables", not "member variables".
The above defines a public getter and private setter that is synthesized automatically. For clarity's sake, I also added a public method and a private method.
"Public" and "private" in Objective-C are defined entirely by visibility to the compiler. The setter for myMutableArray and the method doSomethingInPrivate are only private because their declarations in an #interface cannot be imported.
self.myMutableArray and [self myMutableArray] do the same thing; the . syntax is merely short hand for an equivalent method call (with a few edge case details beyond this question)
#property in the #interface is purely short hand for method declarations (with a bit of extra metadata).
#interface Foo() is a class extension and not a category. It exists for exactly the purpose demonstrated above; to extend the #interface of a class with additional declarative information whose scope should be limited. It can appear in a header file that, say, you only import in your library's implementation to create library-private functionality.
#dynamic is used when you neither #synthesize an #property nor provide a conventional method implementation. It is not needed otherwise!
I'm probably forgetting something.

Hide instance variable from header file in Objective C

I came across a library written in Objective C (I only have the header file and the .a binary).
In the header file, it is like this:
#interface MyClass : MySuperClass
{
//nothing here
}
#property (nonatomic, retain) MyObject anObject;
- (void)someMethod;
How can I achieve the same thing? If I try to declare a property without its corresponding ivar inside the interface's {}, the compiler will give me an error. Ultimately, I want to hide the internal structure of my class inside the .a, and just expose the necessary methods to the header file. How do I declare instance variables inside the .m? Categories don't allow me to add ivar, just methods.
For 64 bit applications and iPhone applications (though not in the simulator), property synthesis is also capable of synthesizing the storage for an instance variable.
I.e. this works:
#interface MyClass : MySuperClass
{
//nothing here
}
#property (nonatomic, retain) MyObject *anObject;
#end
#implementation MyClass
#synthesize anObject;
#end
If you compile for 32 bit Mac OS X or the iPhone Simulator, the compiler will give an error.
You may use of the same idiom used in Cocoa classes. If you have a look to NSString class interface in NSString.h you'll see that there is no instance variable declared. Going deeper in GNUstep source code you'll find the trick.
Consider the following code.
MyClass.h
#interface MyClass : NSObject
// Your methods here
- (void) doSomething;
#end
MyClass.m
#interface MyClassImpl : MyClass {
// Your private and hidden instance variables here
}
#end
#implementation MyClass
+ (id) allocWithZone:(NSZone *)zone
{
return NSAllocateObject([MyClassImpl class], 0, zone);
}
// Your methods here
- (void) doSomething {
// This method is considered as pure virtual and cannot be invoked
[self doesNotRecognizeSelector: _cmd];
}
#end
#implementation MyClassImpl
// Your methods here
- (void) doSomething {
// A real implementation of doSomething
}
#end
As you can see, the trick consist in overloading allocWithZone: in your class. This code is invoked by default alloc provided by NSObject, so you don't have to worry about which allocating method should be used (both are valid). In such allocWithZone:, you may use the Foundation function NSAllocateObject() to allocate memory and initialize isa for a MyClassImpl object instead of MyClass. After that, the user is dealing with a MyClassImpl object transparently.
Of course, the real implementation of your class shall be provided by MyClassImpl. The methods for MyClass shall be implemented in a way that considers a message receiving as an error.
You can use a class extension. A class extension is similar as category but without any name. On the Apple documentation they just define private methods but in fact you can also declare your internal variables.
MyClass.h
#class PublicClass;
// Public interface
#interface MyClass : NSObject
#property (nonatomic, retain) PublicClass *publicVar;
#property (nonatomic, retain) PublicClass *publicVarDiffInternal;
- (void)publicMethod;
#end
MyClass.m
#import "PublicClass.h"
#import "InternalClass.h"
// Private interface
#interface MyClass ( /* class extension */ )
{
#private
// Internal variable only used internally
NSInteger defaultSize;
// Internal variable only used internally as private property
InternalClass *internalVar;
#private
// Internal variable exposed as public property
PublicClass *publicVar;
// Internal variable exposed as public property with an other name
PublicClass *myFooVar;
}
#property (nonatomic, retain) InternalClass *internalVar;
- (void)privateMethod;
#end
// Full implementation of MyClass
#implementation MyClass
#synthesize internalVar;
#synthesize publicVar;
#synthesize publicVarDiffInternal = myFooVar
- (void)privateMethod
{
}
- (void)publicMethod
{
}
- (id)init
{
if ((self = [super init]))
{
defaultSize = 512;
self.internalVar = nil;
self.publicVar = nil;
self.publicVarDiffInternal = nil; // initialize myFooVar
}
return self;
}
#end
You can give MyClass.h to anyone with just your public API and public properties. On MyClass.m you declare your member variable private and public, and your private methods, on your class extension.
Like this it's easy to expose public interfaces and hide detail implementation. I used on my project without any troubles.
According to the documentation I've been looking at there is no problem. All you have to do to hide instance variables is to declare them at the start of the #implementation section, inside { ... }. However, I'm a relative newcomer to Objective C and there's a chance I have misunderstood something - I suspect that the language has changed. I have actually tried this system, using XCode 4.2, building code for the iPad, and it seems to work fine.
One of my sources for this idea is the Apple developer documentation at http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocDefiningClasses.html, which gives this pattern:
#implementation ClassName
{
// Instance variable declarations.
}
// Method definitions.
#end
Two possibilities:
It could be taking advantage of the modern runtime's ability to synthesize instance variables, as bbum suggested.
The property might not have an underlying instance variable in that class. Properties do not necessarily have a one-to-one mapping with instance variables.
No you can't. But you can do this if you're not using #property:
.h
#interface X : Y {
struct X_Impl* impl;
}
-(int)getValue;
#end
.m
struct X_Impl {
int value;
};
...
#implementation X
-(void)getValue {
return impl->value * impl->value;
}
#end
How about a macro trick?
Have tested code below
have tested with dylibs - worked fine
have tested subclassing - Warning! will break, I agree this makes the trick not that useful, but still I think it tells some about how ObjC works...
MyClass.h
#interface MyClass : NSObject {
#ifdef MYCLASS_CONTENT
MYCLASS_CONTENT // Nothing revealed here
#endif
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, assign) int extra;
- (id)initWithString:(NSString*)str;
#end
MyClass.m
// Define the required Class content here before the #import "MyClass.h"
#define MYCLASS_CONTENT \
NSString *_name; \
int _extra; \
int _hiddenThing;
#import "MyClass.h"
#implementation MyClass
#synthesize name=_name;
#synthesize extra=_extra;
- (id)initWithString:(NSString*)str
{
self = [super init];
if (self) {
self.name = str;
self.extra = 17;
_hiddenThing = 19;
}
return self;
}
- (void)dealloc
{
[_name release];
[super dealloc];
}
#end
DON'T do this, but I feel it should be noted that the runtime has the ability to add ivars whenever you want with class_addIvar
I was able to do the following in my library:
myLib.h:
#interface MyClass : SomeSuperClass <SomeProtocol> {
// Nothing in here
}
- (void)someMethods;
#end
myLib.m
#interface MyClass ()
SomeClass *someVars;
#property (nonatomic, retain) SomeClass *someVars;
#end
#implementation MyClass
#synthesize someVar;
- (void)someMethods {
}
#end
The protocol is optional of course. I believe this also makes all your instance variables private though I'm not 100% certain. For me it's just an interface to my static library so it doesn't really matter.
Anyway, I hope this helps you out. To anyone else reading this, do let me know if this is bad in general or has any unforeseen consequences. I'm pretty new to Obj-C myself so I could always use the advice of the experienced.
I don't think the following code written in another answer is working as expected.
The "SomeClass *someVars" defined in the extension class is not an instance variable of MyClass. I think it is a C global variable. If you synthesize someVars, you will get compile error. And self.someVars won't work either.
myLib.h
#interface MyClass : SomeSuperClass <SomeProtocol> {
// Nothing in here
}
- (void)someMethods;
#end
myLib.m
#interface MyClass ()
SomeClass *someVars;
#property (nonatomic, retain) SomeClass *someVars;
#end
#implementation MyClass
#synthesize someVar;
- (void)someMethods {
}
#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! :-)