Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 443 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I create delegates in Objective-C?

#1
I know how delegates work, and I know how I can use them.

But how do I create them?
Reply

#2
When using the formal protocol method for creating delegate support, I've found that you can ensure proper type checking (albeit, runtime, not compile time) by adding something like:

if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
[NSException raise:@"MyDelegate Exception"
format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}

in your delegate accessor (setDelegate) code. This helps minimize mistakes.
Reply

#3
Maybe this is more along the lines of what you are missing:

If you are coming from a C++ like viewpoint, delegates takes a little getting used to - but basically 'they just work'.

The way it works is that you set some object that you wrote as the delegate to NSWindow, but your object only has implementations (methods) for one or a few of the many possible delegate methods. So something happens, and `NSWindow` wants to call your object - it just uses Objective-c's `respondsToSelector` method to determine if your object wants that method called, and then calls it. This is how objective-c works - methods are looked up on demand.

It is totally trivial to do this with your own objects, there is nothing special going on, you could for instance have an `NSArray` of 27 objects, all different kinds of objects, only 18 some of them having the method `-(void)setToBue;` The other 9 don't. So to call `setToBlue` on all of 18 that need it done, something like this:

for (id anObject in myArray)
{
if ([anObject respondsToSelector:@selector(@"setToBlue")])
[anObject setToBlue];
}

The other thing about delegates is that they are not retained, so you always have to set the delegate to `nil` in your `MyClass dealloc` method.
Reply

#4
Please! check below simple step by step tutorial to understand how Delegates works in iOS.

> [**Delegate in iOS**][1]

I have created two ViewControllers (for sending data from one to another)

1. FirstViewController implement delegate (which provides data).
2. SecondViewController declare the delegate (which will receive data).



[1]:

[To see links please register here]

Reply

#5
I think all these answers make a lot of sense once you understand delegates. Personally I came from the land of C/C++ and before that procedural languages like Fortran etc so here is my 2 min take on finding similar analogues in C++ paradigm.

If I were to explain delegates to a C++/Java programmer I would say

What are delegates ?
These are static pointers to classes within another class. Once you assign a pointer, you can call functions/methods in that class. Hence some functions of your class are "delegated" (In C++ world - pointer to by a class object pointer) to another class.

What are protocols ?
Conceptually it serves as similar purpose as to the header file of the class you are assigning as a delegate class. A protocol is a explicit way of defining what methods needs to be implemented in the class who's pointer was set as a delegate within a class.

How can I do something similar in C++?
If you tried to do this in C++, you would by defining pointers to classes (objects) in the class definition and then wiring them up to other classes that will provide additional functions as delegates to your base class. But this wiring needs to be maitained within the code and will be clumsy and error prone. Objective C just assumes that programmers are not best at maintaining this decipline and provides compiler restrictions to enforce a clean implementation.
Reply

#6
The approved answer is great, but if you're looking for a 1 minute answer try this:

MyClass.h file should look like this (add delegate lines with comments!)

#import <BlaClass/BlaClass.h>

@class MyClass; //define class, so protocol can see MyClass
@protocol MyClassDelegate <NSObject> //define delegate protocol
- (void) myClassDelegateMethod: (MyClass *) sender; //define delegate method to be implemented within another class
@end //end protocol

@interface MyClass : NSObject {
}
@property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate

@end

MyClass.m file should look like this


#import "MyClass.h"
@implementation MyClass
@synthesize delegate; //synthesise MyClassDelegate delegate

- (void) myMethodToDoStuff {
[self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class
}

@end



To use your delegate in another class (UIViewController called MyVC in this case) MyVC.h:

#import "MyClass.h"
@interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate
}

MyVC.m:

myClass.delegate = self; //set its delegate to self somewhere

Implement delegate method

- (void) myClassDelegateMethod: (MyClass *) sender {
NSLog(@"Delegates are great!");
}



Reply

#7
Ok, this is not really an answer to the question, but if you are looking up how to make your own delegate maybe something far simpler could be a better answer for you.

I hardly implement my delegates because I rarely need. I can have ONLY ONE delegate for a delegate object. So if you want your delegate for one way communication/passing data than you are much better of with notifications.

NSNotification can pass objects to more than one recipients and it is very easy to use.
It works like this:

MyClass.m file should look like this

#import "MyClass.h"
@implementation MyClass

- (void) myMethodToDoStuff {
//this will post a notification with myClassData (NSArray in this case) in its userInfo dict and self as an object
[[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData"
object:self
userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]];
}
@end

To use your notification in another classes:
Add class as an observer:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil];

Implement the selector:

- (void) otherClassUpdatedItsData:(NSNotification *)note {
NSLog(@"*** Other class updated its data ***");
MyClass *otherClass = [note object]; //the object itself, you can call back any selector if you want
NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it
}


Don't forget to remove your class as an observer if

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

Reply

#8
Here is a simple method to create delegates

Create Protocol in .h file. Make sure that is defined before the protocol using @class followed by the name of the UIViewController `< As the protocol I am going to use is UIViewController class>.`

**Step : 1 :** Create a new class Protocol named "YourViewController" which will be the subclass of UIViewController class and assign this class to the second ViewController.

**Step : 2 :** Go to the "YourViewController" file and modify it as below:


#import <UIKit/UIkit.h>
@class YourViewController;

@protocol YourViewController Delegate <NSObject>

@optional
-(void)defineDelegateMethodName: (YourViewController *) controller;

@required
-(BOOL)delegateMethodReturningBool: (YourViewController *) controller;

@end
@interface YourViewController : UIViewController

//Since the property for the protocol could be of any class, then it will be marked as a type of id.

@property (nonatomic, weak) id< YourViewController Delegate> delegate;

@end


The methods defined in the protocol behavior can be controlled with @optional and @required as part of the protocol definition.




**Step : 3 :**
**Implementation of Delegate**

#import "delegate.h"

@interface YourDelegateUser ()
<YourViewControllerDelegate>
@end

@implementation YourDelegateUser

- (void) variousFoo {
YourViewController *controller = [[YourViewController alloc] init];
controller.delegate = self;
}

-(void)defineDelegateMethodName: (YourViewController *) controller {
// handle the delegate being called here
}

-(BOOL)delegateMethodReturningBool: (YourViewController *) controller {
// handle the delegate being called here
return YES;
}

@end


//test whether the method has been defined before you call it

- (void) someMethodToCallDelegate {
if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
[self.delegate delegateMethodName:self];
}
}
Reply

#9
# Swift version

A delegate is just a class that does some work for another class. Read the following code for a somewhat silly (but hopefully enlightening) Playground example that shows how this is done in Swift.

// A protocol is just a list of methods (and/or properties) that must
// be used by any class that adopts the protocol.
protocol OlderSiblingDelegate: class {
// This protocol only defines one required method
func getYourNiceOlderSiblingAGlassOfWater() -> String
}

class BossyBigBrother {

// The delegate is the BossyBigBrother's slave. This position can
// be assigned later to whoever is available (and conforms to the
// protocol).
weak var delegate: OlderSiblingDelegate?

func tellSomebodyToGetMeSomeWater() -> String? {
// The delegate is optional because there might not be anyone
// nearby to boss around.
return delegate?.getYourNiceOlderSiblingAGlassOfWater()
}
}

// PoorLittleSister conforms to the OlderSiblingDelegate protocol
class PoorLittleSister: OlderSiblingDelegate {

// This method is repquired by the protocol, but the protocol said
// nothing about how it needs to be implemented.
func getYourNiceOlderSiblingAGlassOfWater() -> String {
return "Go get it yourself!"
}

}

// initialize the classes
let bigBro = BossyBigBrother()
let lilSis = PoorLittleSister()

// Set the delegate
// bigBro could boss around anyone who conforms to the
// OlderSiblingDelegate protocol, but since lilSis is here,
// she is the unlucky choice.
bigBro.delegate = lilSis

// Because the delegate is set, there is a class to do bigBro's work for him.
// bigBro tells lilSis to get him some water.
if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() {
print(replyFromLilSis) // "Go get it yourself!"
}

In actual practice, delegates are often used in the following situations

1. When a class needs to communicate some information to another class
2. When a class wants to allow another class to customize it

The classes don't need to know anything about each other beforehand except that the delegate class conforms to the required protocol.

I highly recommend reading the following two articles. They helped me understand delegates even better than the [documentation][1] did.

- [What is Delegation? – A Swift Developer’s Guide][2]
- [How Delegation Works – A Swift Developer’s Guide][3]


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#10
lets say you have a class that you developed and want to declare a delegate property to be able to notify it when some event happens :


@class myClass;

@protocol myClassDelegate <NSObject>

-(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param;

@optional
-(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param;

@end


@interface MyClass : NSObject

@property(nonatomic,weak)id< MyClassDelegate> delegate;

@end

so you declare a protocol in `MyClass` header file (or a separate header file) , and declare the required/optional event handlers that your delegate must/should implement , then declare a property in `MyClass` of type (`id< MyClassDelegate>`) which means any objective c class that conforms to the protocol `MyClassDelegate` , you'll notice that the delegate property is declared as weak , this is very important to prevent retain cycle (most often the delegate retains the `MyClass` instance so if you declared the delegate as retain, both of them will retain each other and neither of them will ever be released).

you will notice also that the protocol methods passes the `MyClass` instance to the delegate as parameter , this is best practice in case the delegate want to call some methods on `MyClass` instance and also helps when the delegate declares itself as `MyClassDelegate` to multiple `MyClass` instances , like when you have multiple `UITableView's` instances in your `ViewController` and declares itself as a `UITableViewDelegate` to all of them.

and inside your `MyClass` you notify the delegate with declared events as follows :

if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)])
{
[_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param];
}

you first check if your delegate responds to the protocol method that you are about to call in case the delegate doesn't implement it and the app will crash then (even if the protocol method is required).
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through