iOS Protocol/Delegate Confusion

iOS Protocol / Delegate confusion?

Basically this is the example of custom delegates and it is used for sending messages from one class to another. So for sending message in another class you need to first set the delegate and then conforming the protocol in another class as well. Below is the example:-

B.h class

@protocol sampleDelegate <NSObject>
@required
-(NSString *)getDataValue;
@end
@interface BWindowController : NSWindowController
{
id<sampleDelegate>delegate;
}
@property(nonatomic,assign)id<sampleDelegate>delegate;
@end

In B.m class

- (void)windowDidLoad
{
//below only calling the method but it is impelmented in AwindowController class
if([[self delegate]respondsToSelector:@selector(getDataValue)]){
NSString *str= [[self delegate]getDataValue];
NSLog(@"Recieved=%@",str);
}
[super windowDidLoad];
}

In A.h class

@interface AWindowController : NSWindowController<sampleDelegate> //conforming to the protocol

In A.m class

 //Implementing the protocol method 
-(NSString*)getDataValue
{
NSLog(@"recieved");
return @"recieved";
}
//In this method setting delegate AWindowController to BWindowController
-(void)yourmethod
{

BWindowController *b=[[BWindowController alloc]init];
b.delegate=self; //here setting the delegate

}

What exactly are protocols and delegates and how are they used in IOS?

Protocols are a way to specify a set of methods you want a class to implement if it wants to work with one of your classes. Delegates and Data Sources like UITableViewDelegate and UITableViewDataSource are protocols indeed.

You specify a protocol this way:

@protocol MyProtocol <NSObject>

- (void)aRequiredMethod;

@required
- (void)anotherRequiredMethod;

@optional
- (void)anOptionalMethod;

@end

Methods declared after the @required or before any other specifier are required and the classes that want to use your protocol need to implement all of them. You can also declare some optional methods by declaring them after the @optional specifier.

You then can specify that a class "conforms" to a protocol (implements the required methods) in the interface of the class:

@interface MyClass <MyProtocol>

@end

You usually keep a reference to an object conforming to a protocol using a property. For example, to keep track of a delegate:

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

At this point, in your code, you just have to call the method you want to call on the object that you're keeping reference of and that implements your protocol as you would with any other method:

[self.delegate aRequiredMethod];

To check whether an object conforms to a protocol you can call

[self.delegate conformsToProtocol:@protocol(MyProtocol)]

To check whether an object implements a method you can call

[self.delegate respondsToSelector:@selector(anOptionalMethod)]

For more information, check the Apple's guide Working With Protocols.

How do I know when to use protocols and delegates, and what are they? ( swift 4.2 )


Protocol:

Think of a protocol as a lingo. It's a specialized vocabulary that objects use to talk to each other. A protocol defines a set of methods and properties that any object that "conforms" to that protocol is guaranteed to have.

Imagine a short-order cook. The short order cook knows the lingo of the restaurant. "I need a #7, well, with everything but onions."

The wait staff doesn't need to know who is working that night. They just place their orders, and the cook cooks them. In fact, the cook doesn't even need to be human. If you could build a robot who understood and could follow the short-order-cook protocol, and could cook the food, you could replace the human with the robot, and the wait-staff wouldn't need to change how they worked at all.

A protocol is very much like that.

Delegates use protocols, but that's not the only way they are used.



Delegate:

A delegate is an object that does a specific job, and that is guaranteed to understand a specific protocol. In the example above, the short-order-cook is the delegate of the restaurant. You don't know what a delegate object is - you just know that it knows how to cook food. You could replace the short order cook with a different short-order cook, and everything works exactly the same as long as they both conform to the short-order-cook protocol. (A delegate is usually defined as an object that conforms to a protocol rather than being a specific class.)

A delegate can also be an object that is used to customize the behavior of another object. For UITableViews, for example, the delegate does things like specify the row height for cells, determines which cells can be selected, handles selection actions, provides header/footer views, and stuff like that.

You frequently provide a delegate to customize the behavior of complex Apple UI objects like table views.

In Swift, does an object conforming to a protocol absolutely need a delegate variable in order to work with the protocol?


If the object already conforms to the protocol by implementing the variables and/or methods, then what is the reason for creating a variable called delegate and setting the type to that of the protocol?

The whole purpose of the protocol in the protocol-delegate pattern is that the only thing this class, which is going to be sending delegate messages to the delegate, needs to know or care about, is that the delegate is an adopter of that protocol — i.e., that it implements the variables / methods. This class doesn't need to know the actual class of the delegate; it just needs to know that that the delegate can be sent the delegate messages.

Thus, it's all about the compiler. The object acting as delegate may conform to the protocol, but the compiler doesn't know that unless this variable is typed as a protocol-adopter. And if the compiler doesn't know, it won't let us send delegate messages to the delegate object! So that's how we type it. That's the minimum the compiler needs to know in order to allow us to send the delegate messages.

UITableview/UIView Delegate Confusion

Agree with @Piotr that the menu must be the table's delegate, so replace self.table.delegate = delegate; with self.table.delegate = self; in MenuView.m.

But additionally, MenuView.m never invokes its delegate, which it should upon selection in the tableview....

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self hideDropDown:self.btnSender];

// remove this, since it does nothing
//[self myDelegate];

// replace it with
[self.myDelegate menuDelegateMethod:self];
}

That last line says, tell the delegate of the menu that something happened.

Another problem is that the menu doesn't really tell the delegate what happened. Certainly the delegate will be interested in which item is selected. Consider changing the protocol to something like:

@protocol MenuViewDelegate
- (void)menuView:(MenuView *)sender didSelectOptionAtIndex:(NSInteger)index;
@end
// calling it
[self.myDelegate menuView:self didSelectOptionAtIndex:indexPath.row];

Another alternative is to hand back the selected string to the delegate. This can be found in the tableview's datasource at the indexPath.row.

Finally, its good practice to not-retain your delegate since the customer of the Menu might retain it, resulting in a retain cycle. Instead, declare the delegate:

// notice "weak"
@property (nonatomic, weak) id <MenuViewDelegate> delegate;

Protocol/Delegate is not working

You create class and this class destroying after you leave viewDidLoad method.

- (void)viewDidLoad {
[super viewDidLoad];

CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"];
cVC.mydelegate = self;
}

As I understand you need to perform some methods in the ViewController from the CViewController.

You can pass viewController as delegate from the BViewController and them past it to the CViewController.

Or you can use code like this:

- (IBAction)cNextAction:(id)sender {
id< testDelegates > delegate = self.navigationController.viewControllers[0];
if([delegate conformsToProtocol:@protocol(testDelegates)])
{
[delegate TestMethod];
}
}

This is no best way but it's will be work.

UIWebView Delegate Confusion

First of all, you need to understand the concept of delegation. A delegate can be an object which can react on behalf of another object when an event or an action encounters within that object.

For example, you can have a UIViewController which has a UITbleView inside it. The UIViewController can have a UITableViewDelegate. In this case, all UITableViewDelegate methods (heightForRow, ViewForFooter, didSelectRowAtIndexPath, ….) can be implemented via UIViewController. So for example when a cell is selected (didSelectRowAtIndexPath), UIViewController can see what cell is selected and decide what to do with that selection.

In your case, you have an instance of UIWebView in your UIViewController. Your UIViewController will need to be a delegate of the UIWebView.

@interface UIViewController () <UIWebViewDelegate>

and then you set the delegate of your UIWebView property to yourself in viewDidLoad.

[self.webView setDelegate:self];

Now you can call the delegate methods within your viewController.

-(bool)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest (NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;

in your .m file of your view controller and decide what you wanna do with the information you receive from the web view.



Related Topics



Leave a reply



Submit