How do I work between classes in Objective-C? - iphone

At the moment, the majority of my code is in the same viewcontroller, and i'd like to move some of it over to other areas. Such as moving the animations all over to somewhere else. But then how do i reference things which are in another class? And how do i reference back from that class to items in my viewcontroller class? Not going this has always disuaded me from doing it.

there is a couple of ways you can achieve that.
one way is the cocoa delegate #protocol way, the second way could be creating references to each object in the other class.
for the first way you can do something like this:
#class Class2;
#interface Class1 : NSObject {
Class2 *cls2Pointer;
}
#property Class2 *cls2Pointer;
#end
#class Class1;
#interface Class2 : NSObject {
Class1 *cls1Pointer;
}
#property Class1 *cls1Pointer;
#end
int main(){
Class1 cls1Obj = [[Class1 alloc] init];
Class2 cls2Obj = [[Class2 alloc] init];
[cls1Obj setCls2Pointer:cls2Obj];
[cls2Obj setCls1Pointer:cls1Obj];
}
the second way, is to declare a protocol in one/both of the classes to be able to pass arguments and call different methods on other objects:
#protocol Class1Delegate
- (void)class1:(Class1)obj MethodWithArg:(id)arg;
#end
#interface Class1 : NSObject {
id <Class1Delegate> delegate;
}
#end
#interface Class2 : NSObject <Class1Delegate>{
}
#end
#implementation Class2
- (void)class1:(Class1)obj MethodWithArg:(id)arg {
//do stuff when called from the 1st class
}
#end

You might like to look into this here - to create static classes in objective c and then reference them in a separate file by classname - as in the view controller quoted in the linked example.
Otherwise you can just create a new class within a separate .m file and then code it such that the calling method in another class will first create an instance of this new class and then invoke the necessary method on this instance.
Hope this helps.

Basically what you do is that you create one or more classes, move the code over to these classes and then create instances of these classes in your viewcontroller.
so if you had a method in your view controller
-(void)foo;
you would create a new class say C and move the method there.
then in your view controller you would create an instance variable of that class e.g.
C* myC;
then alloc/init and then call the foo method. This is not object oriented in the sense that foo is not really related to C in any way so method foo could have just been a static method not relating to the instance and as such called just like any other method but as [C foo] instead of [self foo] from the view controller.
the other more OOP method would be to move functionality that belongs to together into a separate class like animation in your example.

Related

How to work with inheritance in objective-C (iOS sdk)

I just started to learn iOS programming and I have a problem with inheritance. There are 2 files.
First file
Header
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
int x;
}
#end
Implementation:
#import "ViewController.h"
#import "NewClass.h"
#implementation ViewController
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
x = 999;
NewClass *myClass = [[[NewClass alloc] init] autorelease];
}
#end
Second file
Header:
#import "ViewController.h"
#interface NewClass : ViewController
#end
Implementation:
#import "NewClass.h"
#implementation NewClass
-(id)init {
self = [super init];
if (self != nil) {
NSLog(#"%i",x);
}
return self;
}
#end
In ViewController I set x to 999, and in NewClass I want to get it, but when I call NSLog(#"%i",x); it gives me 0.
Where did I make a mistake?
You have a timing problem.
The init method gets called first (at all levels of the inheritance hierarchy, so in both ViewController and NewClass). This is when you print out your value of x, when it is still zero.
The viewDidLoad method only gets called much later, generally at a point after a view controller's view has been added to a superview. It's functionality that's specific to the UIViewController class.
To make your example work, put an init method in your ViewController class that looks like the one in your NewClass class, and set x there.
Also, you don't need to create a NewClass instance within ViewController. When you create a NewClass object, it is automatically a ViewController as well. In the same way that a dog is an animal automatically, and so is a cat. When you create a dog, you don't want to create an animal as well!
As sidyll says, you should probably do a bit more reading about how inheritance works, I'm afraid!
You need to review you OOP concepts. Object-Oriented Programming with Objective-C is a must.
Your class NewClass indeed inherits the x variable, but not it's value. When you create an instance of it, you're creating a shiny new instance whose values have nothing to do with the parent class.
Another point of view to help you is that x was set in a object of ViewController class. The NewClass inherits from ViewController class, not from an arbitrary instance (object, where you set x).
That's because -viewDidLoad is not called until well after -init returns. Your superclass should do configuration like that in its -init method.

Unable to access object of other class

I am accessing object of one class in the another class. But instance variable is Showing null.
This is my code.
fvcObj = [[FirstViewController alloc]init];
NSLog(#"%#",fvcObj.user);
Which things to take care in declaring object of another class?
Thanks.
As PengOne has said it is a new instance of the class FirstViewController and it cannot hold the data which you have assinged to the "user" variable in FirstViewController class. I think you want to pass data from one view controller class to other. If so then declare a method in the class to which you want to send the data and call this method from the other class and pass the data as a parameter of the method.
Hope this might help u.
Happy coding
fvcObj
is a new instance of FirstViewController, so my guess is that the user property has yet to be defined.
In header file (*.h) for example:
#interface MyClass : NSObject
{
NSString *someString;
}
#end
#property (nonatomic,retain) someString;
In implementation file (*.m)
#synthesize someString
This create setter and getter for someString

Objective-C design pattern question about delegate

I have a class which implements many delegate methods. How to group the delegate methods into different classes by the protocol they belongs to and use them in the original class?
Rather than creating many classes, a simpler solution is to divide the class into different categories:
#interface MyViewController : UIViewController {
...
}
...
#end
#interface MyViewController (TableStuff) <UITableViewDataSource, UITableViewDelegate>
// methods related to table stuff
#end
#interface MyViewController (SearchStuff) <UISearchBarDelegate>
// methods related to table stuff
#end
Since categories just add methods to the existing class, you could use the any methods declared in a category in the "original" class.

instance method of class for iphone

i want to create some header file for future use but i have 1 problem
i have defined a method in lets say Rimage class called check1
now i want to call that from maiviewcont
so i did this
in mainVC.h
i defined a instance of Rimage class
#import <UIKit/UIKit.h>
#class Rimage;
#interface Rahul_imageplaceCordinatesViewController : UIViewController {
Rimage *aRimage;
}
#property (nonatomic,copy) Rimage *aRimage;
#end
and in .m
[self.aRimage check1];
aRimage = [Rimage check1];
but both are not working
i went for both +(void)check1 and -(void)check1 in Rimage class
The two examples you give do very different things:
[self.aRimage check1];
invokes an check1 instance method on aRimage.
aRimage = [Rimage check1];
calls the check1 class method on the Rimage class, and assigns the result to aRimage.
In both cases, you will need to #import "Rimage.h in your .m file, else you'll get warnings like "aRimage may not respond to 'check1'".
EDIT
Your ".h" file is declaring a property named "aRimage", but that value will be nil until you assign something to it, by doing something like:
self.aRimage = [[[Rimage alloc] init] autorelease];
See this question for a good explanation of the difference between class methods and instance methods.
ps. and don't forget to do a [aRimage release] in your dealloc method

cocoa - referencing a method on the parent

I had a method on my main view controller named "calculateThis".
This method was run, obviously, as
int newValue = [self calculateThis:myVariable];
when I run it from inside the view controller.
Then I created a static class and I need to run this method from there.
How do I reference this method from that class using just relative references, as super, superview, delegate, etc. I cannot use the class name defined on the delegate because this static class is used in several apps of mine.
I need to go up in the hierarchy, I imagine one level, and access the method there...
thanks.
Define your utility methods in a category on NSObject or related subclasses of NSObject.
Which you have done.
Adding (id)sender to your method will work. Then your method can reference the object that called it. Something like this.
+(int)calculateThis:(id)sender userInfo:(id)info;
then your call becomes.
int newValue = [NSObject calculateThis:self userInfo:myVariable];
If your intent is to create a class that you can use without initializing it, that's possible using class methods. For instance, if I want to make a class called MyClass with a doSomethingWith: method, I would define the following:
In MyClass.h:
#interface MyClass : NSObject {
}
+(void)doSomethingWith:(id)thisObject;
#end
In MyClass.m:
#import "MyClass.h"
#implementation MyClass
+(void)doSomethingWith:(id)thisObject
{
// Your code goes here.
}
#end
To reference this method in another class, you can use the class object for MyClass like so:
[MyClass doSomethingWith:#"Hello, World!"];
This isn't really a typical Cocoa or Cocoa Touch design pattern, but can be handy for things like calculations.
Are you talking about the superclass? If so, you use [super ...].