Using a protocol and a delegate

2019-09-15 01:20发布

问题:

I am trying to get some code in a view working. I have declared a delegate and it does not get instantiated, any Idea what I am missing? I have tried to summarise how I have done this below. I think that the issue is that somewhere, my dataSource delegate needs to be instantiated.

I have a View called graph view and a delegate that is in the viewcontroller GraphViewController.

I know that the method in GraphView is doing something as it calls the AxisDrawing helper class and draws in Axes.

Here is the relevant code

In GraphView.h I set up the protocol and the dataSourceDelegate

@class GraphView;

@protocol GraphViewDataSourceDelegate
- (float)functionOfX:(float)xValue inGraphView:(GraphView *)sender;
@end

@interface GraphView : UIView

@property(nonatomic, weak) IBOutlet id <GraphViewDataSourceDelegate> dataSourceDelegate;

@end

Which I synthesize in GraphView.m

#import "GraphView.h"
#import "AxesDrawer.h"

@implementation GraphView

@synthesize dataSourceDelegate = _dataSourceDelegate;

Also in Graph View I try to use the delegate as follows (pixel is a CGPoint). This routine does run and I can draw to GraphView from here provided I do not try to use my protocol method. i.e. Some of my DrawRect stuff does get drawn which checks out the linking of the UIView to my custom View

pixel.y = [self.dataSourceDelegate functionOfX:pixel.x inGraphView:self];

++++Breakpoint put in here+++++

In GraphViewController I state that I implement the protocol and implement it as follows. The compiler warns me and spots when the implementation is done, turning of the warning. (I am only returning 3.0 at the moment as a test).

@interface  

GraphViewController () <GraphViewDataSourceDelegate>
@property (nonatomic, weak) IBOutlet GraphView *graphView;

@end

...

-(float) functionOfX:(float)xValue inGraphView:(GraphView *)sender{
    NSLog(@"fofx accessed");
    return 3.0;
}

If I look at the GraphView* object just after a breakpoint, it seems to have no instance. What am I missing out.

This is from the trace at the breakpoint

_dataSourceDelegate struct objc_object * 0x0

EDIT: (In addition to @Clays answer below)

It turned out that my connection to the custom view was broke. This meant that the fault lay with the View not talking to the Custom ViewController. The link is made by ctrl dragging from the View Controller button in the Interface builder to the View within the ViewController.

This caused the ViewController to be instantiated and everything then worked fine.

To put it another way.

The link in question was the Outlet. This has to be declared in the ViewController as a property and then linked in IB using ctrl Drag from the ViewController Name-Bar to the View in the Controller.

Provided that you have added the Outlet property correctly, when you do the ctrl drag, your view will appear an option.

The context button popup information on the ViewController button in IB does give a clue.

If you have neglected to put the outlet property into the view controller, the link does appear in the context button popup but it is greyed out, and when you do the link your View is not named.

Once you put the outlet in, the name appears in the menu but not greyed out.

回答1:

Make sure you've hooked everything up correctly: setting your GraphView's dataSourceDelegate, and your GraphViewController's graphView.

From the trace it looks like you haven't done that; or you lose the reference somewhere along the way because at some point nothing's holding on to it.