iPhone: Sharing protocol/delegate code - iphone

I have the following code protocol snippets:
#protocol FooDelegate;
#interface Foo : UIViewController {
id delegate;
}
...
#protocol FooDelegate
... // method 1
... // method 2
...
#end
Also, the following code which implements FooDelegate:
#interface Bar1 : UIViewController { ... }
#interface Bar2 : UITableViewController { ... }
It turns out the implementation of FooDelegate is the same on both Bar1 and Bar2 classes. I currently just copy FooDelegate implementation code from Bar1 to Bar2.
How do I structure/implement in such a way that Bar1 and Bar2 share the same code in a single code base (not as currently with 2 copies) since they are the same?
Thanks in advance for your help.

Option A: Implement the method in a Category
Any properties used must be declared in UIViewController.
UITableViewController is a subclass of UIViewController.
//UIViewController+MyAdditions.h
#interface UIViewController (MyAdditions)
- (void)myCommonMethod;
#end
//UIViewController+MyAdditions.m
#implementation UIViewController (MyAddtions)
- (void)myCommonMethod {
// insert code here
}
The new method added to UIViewController will be inherited by Bar1 and Bar2
Option B: Create a MyViewControllerHelper class
If you can, implement your common code as a class method, otherwise you will need to create an instance of your helper class either temporarily or as a property of Bar1 and Bar2
#interface MyViewControllerHelper : NSObject
- (void)myCommonMethod;
#end
#implementation MyViewControllerHelper
- (void)myCommonMethod {
// common code here
}
#interface Bar1 : UIViewController {
MyViewControllerHelper *helper;
}
#property MyViewControllerHelper *helper;
#end
#implementation Bar1
#synthesize helper;
- (void)someMethod {
[helper myCommonMethod];
}
#end
#interface Bar2 : UITableViewController {
MyViewControllerHelper *helper;
}
#property MyViewControllerHelper;
#end
#implementation Bar2
#synthesize helper;
- (void)someOtherMethod {
[helper myCommonMethod];
}
#end

Make a new object, MyFooDelegate:
#interface MyFooDelegate : NSObject <FooDelegate>
Then Bar1 and Bar2 can each create an instance of it (or share one instance). In those classes you can eliminate the delegate methods and add lines like:
MyFooDelegate *myDooDelegateInstance = ...;
foo.delegate = myFooDelegateInstance;
You could also create an instance of MyFooDelegate in a NIB file and connect the view controller's delegate outlets to it, if desired.
That way, you won't have any duplicated code in your source files or in your executables.

Related

ios - How to assign a new class in existing class?

I'm new to iPhone development,I want to assign one class in existing class
This is what declare in C#
public partial class UserRegisteration : System.Web.UI.Page
{
//some methods
public class Mime
{
//some methods
}
}
like the above format in Objective-C how to assign one more class in existing class?
Any ideas? Thanks in advance.
Yes you can.I am using one class in existing class . One is extending UIView and other is extending NSObject.
MultiLayout.h
#interface MultiLayout : UIView
{
// methods and properties
}
#end
#interface SingleControl : NSObject
{
// methods and properties
}
#end
MultiLayout.m
#implementation SingleControl
//methods and variables declaration and property synthesization
#end
#implementation MultiLayout
//methods and variables declaration and property synthesization
#end
For getting the static value of SingleControl in MultiLayout . you have to call class method like:
MultiLayout.h
#interface MultiLayout : UIView
{
// methods and properties
}
#end
#interface SingleControl : NSObject
{
// methods and properties
}
// add class method
+(int)getValue;
#end
MultiLayout.m
#implementation SingleControl
// add static value
static int values = 100;
// implement method
+(int)getValue{
return values;
}
#end
#implementation MultiLayout
// call method to get value
[SingleChoiceControl getValue];
#end
If I understand your question correctly, you would do this in your interface file:
#interface Mime
//properties and method declarations
#end
#interface UserRegistration : System.Web.UI.Page
#property (strong, nonatomic) Mime *mimeInstance;
#end
and then in the implementation file you implement both like so:
#implementation Mime
//implementation
#end
#implementation UserRegistration
//implementation
#end

How to put more than one subclass in objective c

How can I do something like this ?
#interface SomeClass:NSViewController **:NSTableViewController** #end
How can i put two subclases in my class ??
Objective-C does not support Multiple Inheritance.
Typically, you work around this by using protocols when you want to program to an interface.
#interface SomeClass : NSViewController < SomeProtocol >
#end
Another option is composition:
#interface SomeClass : NSObject
{
#private
NSViewController * viewController;
NSTableViewController * tableViewController;
}
#end

Understanding Protocol Inheritance in Objective-C

I'll appreciate if anyone can explain the logic behind protocol inheritance. e.g. what does the following mean (UITableView.h):
#protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
The following class implementation doesn't work. I have a class View1 (which inherits UIView), with an associated protocol. I have another class, View2 (which inhertits View1). Now i want to inherit the the protocol as well. Can anyone please point me in the right direction.
Class 1:
#protocol View1Delegate;
#interface View1 : UIView {
id <View1Delegate> delegate;
// . . .
}
#property (nonatomic, assign) id <View1Delegate> delegate; // default nil. weak reference
#end
#protocol View1Delegate <NSObject>
- (void)View1DelegateMethod;
#end
#implementation View1
#synthesize delegate;
// . . .
#end
Class 2:
#protocol View2Delegate;
#interface View2 : View1 {
id <View2Delegate> delegate;
// . . .
}
#property (nonatomic, assign) id <View2Delegate> delegate; // default nil. weak reference
#end
#protocol View2Delegate <NSObject>
- (void)View2DelegateMethod;
#end
#implementation View2
#synthesize delegate;
// . . .
#end
Think of it more as composition rather than inheritance.
#protocol UITableViewDelegate<NSObject, UIScrollViewDelegate> defines a protocol that includes all the methods of the NSObject protocol, the UIScrollViewDelegate protocol, as well as any methods defined for the UITableViewDelegate protocol. When you subclass and create a new property, you're overriding the type of the superclasses property. To make this work how I think you want, you should declare View2Delegate as #protocol View2Delegate <NSObject, View1Delegate>.
It's exactly the same as the inheritance of interfaces in Java (interface UITableViewDelegate extends NSObject, UIScrollViewDelegate), C# (interface UITableViewDelegate : NSObject, UIScrollViewDelegate), etc.

Send an event to call a method between two classes

How can I invoke a method in a class only after verifying a condition in another method of another class in my iPhone app?
Any ideas?
Thanks, Andrea
edit 3
//class1
//Class1.m
#implementation Class1 {
....
[class2 method1:#"file1.xml"];
[class2 method1:#"file2.xml"];
[class2 method1:#"file3.xml"];
}
….
#end
//class2
#import "Class1.h"
#implementation Class2{
-(void) method1(NSString *)file{
[self method2];
}
-(void) method2{
//when finish that method I have to call the successive method [class2 method1:#"file2.xml"]; in class1
}
}
hope this help to understand (even better) the problem...
You need to use delegation. Making class 1 class 2's delegate lets class 2 send messages to class 1.
Edit changes: You want class2 to be the delegate of class 1. This means that class 1 will tell class 2 to perform method1 with whatever comes after after the colon. This can be any object. In the example, I used a string. Process method1 as you normally do, but remember that the xmlFile variable should be used instead of a hardcoded object, i.e. use xmlFile instead of #"file1.xml".
EDITED Example:
class 1 .h:
#import <UIKit/UIKit.h>
..etc
//a protocol declaration must go before #interface
#protocol class1Delegate
-(void)method1:(NSString *)xmlFile;
#end
#interface class1 {
id <class1Delegate> delegate;
}
#property (nonatomic, assign) id <class1Delegate> delegate;
#end
Synthesize delegate in your .m
Then call [delegate method1:#"file1"].
class 2 .h:
#import "class1.h"
#interface class2 <class1Delegate> {
//put whatever here
}
- (void)method1:(NSString *)xmlFile;

Can protocols within protocols be treated as inclusive of the protocol they adopt?

I am assigning protocols in a couple classes that follow an inheritance tree. Like so:
first class
#protocol LevelOne
- (void) functionA
#end
#interface BaseClass : NSObject <LevelOne> {
}
second class
#protocol LevelTwo <LevelOne>
- (void) functionB
#end
#interface SubClass : BaseClass <LevelTwo> {
}
Later I am assigning the class as delegate properties of other classes
base class
#interface AppClass : NSObject {
#protected
id<LevelOne> levelOneDelegate;
}
#property (assign) id<LevelOne> levelOneDelegate;
subclass
#interface AppClassesFriend : AppClass {
#protected
id<LevelTwo> levelTwoDelegate;
}
#property (assign) id<LevelTwo> levelTwoDelegate;
At the end of this journey, AppClassesFriend has 2 properties on it.
"levelOneDelegate" has access to "functionA", when it is assigned with a BaseClass object.
However, I am finding that "levelTwoDelegate" only has access to "functionB" (it is assigned with a SubClass object).
In order to have AppClassesFriend be able to use both functions, it seems I need to assign BOTH a levelOneDelegate AND levelTwoDelegate.
Is there any way to make "levelTwoDelegate" have access to both? Since, both functions are available on "SubClass".
So, what I would like to be able to do is :
SubClass *s = [SubClass alloc];
AppClassesFriend *a = [AppClassesFriend alloc];
a.levelTwoDelegate = s;
so inside AppClassesFriend (a) I could use :
[self.levelTwoDelegate functionA]; <---- this is never found
[self.levelTwoDelegate functionB];
but it seems I have to add
a.levelOneDelegate = s;
Thanks if anyone took the time to read all the way down this far. So in summary the question is, how do I get "levelTwoDelegate" to have access to both functionA and functionB?
Simply declare that your subclass's delegate property implements both level one and level two protocols (i.e. implements both functionA and functionB):
#interface AppClassesFriend : AppClass {
#protected
id<LevelOne,LevelTwo> levelOneAndTwoDelegate;
}
#property (assign) id<LevelOne,LevelTwo> levelOneAndTwoDelegate;