How to access first class method from second class in objective c - iphone

I have written two classes which contains same method (print). I want to access first class print method using second class object. How i can achieve this?
Code:
#interface classA : NSObject
-(void) print;
#end
#implementation classA
-(void) print
{
NSLog(#"hello");
}
#end
#interface classB : classA
-(void) print;
#end
#implementation classB
-(void) print{
NSLog(#"hey");
}
#end
Now i created second class object like
classB *B = [classB alloc]init];

use delegates to access other classes
#protocol

you can do like this way also
#implementation view1
(void)someMethod
{
......code of method...
}
#implementation view2
(void)fistMethod
{
view1 *abc = [[view1 alloc]init];
[abc someMethod];
[abc release];
}
also check this Objective-C call function on another class?

Related

Delegates in iOS

I am a newbie to iOS world, so please ignore the obvious.
I am pushing a viewController(HelpViewController) on top of another viewController(MainViewController). When a particular action happens in the HelpViewController, I would like to update a variable inside the MainViewController. I understand for this I need to use delegate.
Here is my delegate header...
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
// Protocol Definition ends here
#interface ViewDelegate : NSObject
{
// Delegate to respond back
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id delegate;
-(void)sendMessage:(BOOL)status; // Instance method
#end
and implementation...
#implementation ViewDelegate
#synthesize delegate;
-(id)init {
self = [super init];
return self;
}
-(void)sendMessage:(BOOL)status
{
[delegate switchToggled:status];
}
- (void)dealloc
{
[super dealloc];
}
#end
So Now If I want to implement Protocol ViewControllerDelegate I need to specify in MainViewController, which I do as follows --
MainViewController <ViewControllerDelegate>
and
#pragma mark - ViewControllerDelegate delegate
-(void)switchToggled:(BOOL)status{
NSLog(#"Switch Toggled(%d) Message passed to MainViewController",status);
}
My question is how do I specify Object, which delegate property needs to point to, so that it can come back to MainViewController's "switchToggled".
One way I do is by having property inside HelpViewController as follows -
MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.mainView = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
HelpViewController.h
#property (nonatomic) MainViewController *mainView;
HelpViewController.m
#synthesize mainView;
ViewDelegate *myDelegate = [[ViewDelegate alloc] init];
// assign delegate
myDelegate.delegate = mainView;
[myDelegate sendMessage];
[myDelegate release];
Is this correct way to implement or there is better way to achieve this or am I totally wrong.
Thanks
You should do:
// HelpViewController.h
#protocol HelpDelegate
- (void)switchToggled:(BOOL)status;
#end
// HelpViewController.m
#interface HelpViewController : UIViewController
#property (nonatomic, assign) id<HelpDelegate> delegate;
- (id)initWithDelegate:(id<HelpDelegate>)delegate
#end
#implementation HelpViewController
- (id)initWithDelegate:(id<HelpDelegate>)delegate
{
if (self = [super init])
{
self.delegate = delegate;
}
}
- (void)sendMessage:(BOOL)status
{
[self.delegate switchToggled:status];
}
// MainViewController.h
#import "HelpViewController.h"
#interface MainViewController.h : UIViewController <HelpDelegate>
// MainViewController.m
- (void)someMethod
{
HelpViewController* viewController;
viewController = [HelpViewController alloc] initWithDelegate:self];
...
}
#pragma mark - Help Delegate
- (void)switchToggled:(BOOL)status
{
...
}
Give the delegate a name that makes clear to which class it belongs.
You don't need the extra class/files for ViewDelegate/ViewControllerDelegate. Just define the delegate in header of class it belongs to: HelpViewController.n in this case.
Similar: Implement the delegate method switchToggled: in the real class MainViewController, and not in the extra/unnecessary class ViewDelegate.
The purpose of delegates is to avoid class dependencies. By including MainViewController in HelpViewController you create such a dependency. This is not necessary as I show, and is wrong design.
You were also creating a circular dependency, because MainViewController already needed HelpViewController in order to show it, and now they need each other the other way around for sending the event.
Alternatively you can make HelpViewController's delegate public, have an init without argument, and expect users to set it with helpViewController.delegate = self; or something. But this would only make sense when the delegate being set is optional (which don't seems the case here, so adding it to the init method is appropriate).
I tell you what I would have done:
1) the protocol definition is ok, but do NOT create the class ViewDelegate, so:
//ViewControllerDelegate.h
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
2) Your implementation of the delegate method in MainViewController is ok.
3) Now... the important point:
//interface
#interface HelpViewController : UIViewController //or whatever superclass..
{
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id<ViewControllerDelegate> delegate;
#end
//implementation
#implementation HelpViewController
- (void)someMethodWhichCallsTheDelegate
{
//do something
...
// call delegate
//if switchToggled: were optional then add the following
//if ([self.delegate respondToSelector:#selector(switchToggled:)]) {
[self.delegate switchToggled:status];
}
#end
4) Now you have to assign the delegate:
//MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.delegate = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
And that's it!
BTW: if this delegate is related only to HelpViewControllerthen add the protocol definition where you define the interface of the class, it is not necessary to create a separate header file. If instead the protocol is "global", then it can have some sense to declare it separately.

confused category in objective-c concept

hi i'm wondering category in objective-c
i have 3 files
A_ViewController
A_ViewController+Category
B_ViewController
here's example code
1-1. A_ViewController.h
#interface A_ViewController {
// some instance Variables
}
//some public methods
#end
1-2 A_ViewController.m
#import "A_ViewController.h."
#implementation A_ViewController
// implementation public methods and private methods
#end
2-1. A_ViewController+Category.h
#interface A_ViewControler(Category)
-(void) categoryMethod;
#end
2-2. A_ViewController+Category.m
#import "A_ViewController.h"
#import "A_ViewController+Category.h"
#implementation A_ViewController(Category)
-(void) categoryMethod {
NSLog(#"it's A_ViewController+Category");
}
#end
3-1. B_ViewController.h
#interface B_ViewController {
// some instance variables
}
-(void) myMethod;
3-2. B_ViewController.m
#import "B_ViewController.h"
#import "A_ViewController.h"
#interface A_ViewController() // i think it's A_ViewController extension, not A_ViewController+Category, am i right?
-(void) categoryMethod;
#end
#implementation B_ViewController
-(void) myMethod
{
A_ViewController *obj = [[A_ViewController alloc] init];
[obj categoryMethod];
}
#end
i thought it's crashed because i'm not import A_ViewController+Category.h
and i'm not implement -(void) categoryMethod in B_ViewController.m
but it works fine, and no warning.
how [obj categoryMethod] can be linked??
if that's perfectly fine syntax, i have extension question.
if i have another category called A_ViewController+Category2
here's A_ViewController+Category.h
#interface A_ViewController(Category2)
-(void) categoryMethod;
#end
and A_ViewController+Category2.m
#import "A_ViewController.h"
#import "A_ViewController+Category2.h"
#implementation A_ViewController(Category2)
-(void) categoryMethod
{
NSLog(#"it's A_ViewController+Category2");
}
#end
and this situation, if i write a code like 3-2,
then [obj categoryMethod] can' be guaranteed
that comes from A_ViewController+Category or A_ViewController+Category2, right?
I'm struggling slightly to work out what you're trying to do but in regard to standard category behaviour.
If you want to call categoryMethod on an instance of A_ViewController from within B_BiewController you need to import the header that contains the category method #interface.
You can't declare the private category () on A_ViewController from within B_ViewController.m, as the private category or class extension is a special category.
B_ViewController.m should look like this
#import "B_ViewController.h"
#import "A_ViewController+Category.h"
#implementation B_ViewController
- (void) myMethod {
A_ViewController *obj = [[A_ViewController alloc] init];
[obj categoryMethod];
}
#end
Edit
I've just noticed your Category2 method name is the same as your Category method name. This is incorrect and undefined behaviour in Objective C.

In Xcode how to suppress "incomplete implementation"?(inheritance)

I have a method which is implemented in its super method. And when I run my program. It works fine. How do I suppress this warning? By the way, both methods are in '.m' file.
The code is like this:
ClassA.m
#interface ClassA()
- (void)method;
#end
ClassA.h
#interface ClassA : ClassB
#end
ClassB.m
#interface ClassB()
#end
#implementation ClassB
- (void)method
{
}
And it works OK when I call method in ClassA
You could always implement the method anyway, and call the super method -
-(void)doMyThing {
[super doMyThing];
// do nothing
}
You've got it completly wrong. Popular construction is to have:
ClassB.h
#interface ClassB
- (void)method;
#end
ClassB.m
#interface ClassB()
#end
#implementation ClassB
- (void)method
{
//do nothing or even assert false
}
#end
ClassA.h
#interface ClassA : ClassB
#end
ClassA.m
#interface ClassA()
#end
#implementation ClassA
- (void)method
{
//do your stuff here
}
#end
And that's called method overriding. But if I correctly understand what you are trying to achieve you should have:
ClassB.h
#interface ClassB
- (void)method;
#end
ClassB.m
#interface ClassB()
#end
#implementation ClassB
- (void)method
{
//do your stuff here
}
#end
ClassA.h
#interface ClassA : ClassB
#end
And there is no need to mess up with ClassA, and you can call
ClassA *o=[[ClassA alloc ] init];
[o method];
Then the method is available in classA thanks to inheritance from ClassB.
Sounds like you've declared the method in the .h file when you shouldn't have? Or perhaps the #end is missing from the .h file.
You aren't giving us much to go on. Can we see your full code from the .h and .m?
Having read your code sample, try the following:
ClassA.h
#interface ClassA : ClassB
//ClassB inherits from Class A, so we define 'method' in Class B
//ClassA knows about 'method' by inheritance from class B,
//so 'method' doesn't need to be defined here.
//doStuff will be the method that calls 'method'
- (void)doStuff;
#end
ClassA.m
#interface ClassA
#end
#implementation ClassA
- (void)doStuff
{
//Call 'Method'
[self method];
}
#end
ClassB.h
#interface ClassB
//Define 'method' which will be inherited by ClassA
- (void)method;
#end
ClassB.m
#interface ClassB
#end
#implementation ClassB
- (void)method
{
//'method' does it's thing
NSLog(#"Method has been Called");
}
#end

Accessing NSString from another class returns null. Why?

I have made a simple app to try a nut out the problem; this is also the first time I have used a class method so excuse me if I am doing it wrong.
ViewController.h
#import <UIKit/UIKit.h>
#import "ClassB.h"
#interface ViewController : UIViewController {
NSString *string;
}
#property (nonatomic,retain) NSString *string;
-(void)setString;
-(void)printStringViaClassB;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize string;
- (void)viewDidLoad
{
NSLog(#"I'm inside viewDidLoad");
[super viewDidLoad];
[self setString];
[self printStringViaClassB];
}
-(void)setString {
NSLog(#"I'm inside the setString Method of the ViewController Class");
string = #"HelloWorld";
NSLog(#"String set to: %#",string);
}
-(void)printStringViaClassB {
NSLog(#"I'm inside the printStringViaClassB method of the ViewController Class");
[ClassB printLog];
}
ClassB.h
#import <Foundation/Foundation.h>
#import "ViewController.h"
#class ViewController;
#interface ClassB : NSObject{
}
+(void)printLog;
#end
ClassB.m
#import "ClassB.h"
#implementation ClassB {
}
+(void)printLog {
NSLog(#"I'm in the PrintLog Method of ClassB");
ViewController* VC = [[ViewController alloc] init];
NSLog(#"The set string is: %#",VC.string);
}
#end
This is the resulting log; as you can see, it is showing "(null)" when accessing the string from B instead of HelloWorld.
2011-11-20 14:21:18.223 ClassA[2253:f803] I'm inside viewDidLoad
2011-11-20 14:21:18.224 ClassA[2253:f803] I'm inside the setString Method of the ViewController Class
2011-11-20 14:21:18.225 ClassA[2253:f803] String set to: HelloWorld
2011-11-20 14:21:18.225 ClassA[2253:f803] I'm inside the printStringViaClassB method of the ViewController Class
2011-11-20 14:21:18.226 ClassA[2253:f803] I'm in the PrintLog Method of ClassB
2011-11-20 14:21:18.226 ClassA[2253:f803] The set string is: (null)
When you run the following code: ViewController* VC = [[ViewController alloc] init];, you are creating a NEW instance of ViewController. Since new instances of ViewController don't have their string value until their loaded (i.e., until viewdidload is run), you are simply printing out null.
Try passing in the string value you want to access from the second class as a parameter:
+(void)printLog:(NSString*)log;
+(void)printLog:(NSString*)log {
NSLog(#"I'm in the PrintLog Method of ClassB");
NSLog(#"The set string is: %#",log);
}
to call the function, say [ClassB printLog:string]; instead of [ClassB printLog];

how to pass string value from one class to another

I just want to know that how to pass the string value from one class to another..
Actually i have two classes.In first class i fetch string value from the array and i just want to use this string value into my second class.Now i don't know how to pass value between this two classes.Please give me some idea to do that.Should i use some class method to pass the value.But i don't know how to use this class methods.How i create the class methods to set the values from one class and then get the same value from class methods.
Thanks for help
Class1.h:
#interface Class1 : NSObject
{
NSArray *arr;
}
- (NSString *)myString;
#end
Class1.m:
#implementation Class1
- (NSString *)myString
{
return [arr objectAtIndex:0];
}
#end
Class2.h:
#interface Class2 : NSObject
{
}
- (void)methodThatUsesStringFromClass1:(Class1 *)c1;
#end
Class2.m:
#implementation Class2
- (void)methodThatUsesStringFromClass1:(Class1 *)c1
{
NSLog(#"The string from class 1 is %#", [c1 myString]);
}
#end
The simplest way is to define public #property in class where you want to pass your object, for example, for NSString:
// CustomClassA.h
#interface CustomClassA : NSObject
{
}
#property (nonatomic, retain) NSString *publicString;
#end
// CustomClassA.m
#implementation CustomClassA
#synthesize publicString;
#end
In your sender:
//somewhere defined CustomClassA objectA;
[objectA setPublicString:#"newValue"];
But you should understand what means retain, #synthesize and other. Also it is not your current question.
you can use appDelegate.YourStringVaraible =#"store your string";
and then use this YourStringVaraible in any class by using appDelegate.YourStringVaraible
pass the string parameter by overriding the init method.
Class1.m
#implementation Class1
Class2 *class2 = [[Class2 alloc] initWithString:myString];
...
#end
Class2.h
#interface Class2 : NSObject
{
NSString *string2;
}
#end
Class2.m
-(id) initWithString:(NSString*)str {
self = [super init];
if(self) {
string2 = str;
}
return(self);
}