For some reason the custom setter of a property never gets called. So it is always coming through as nil at runtime.
I have a view controller that creates an NSArray of NSValue objects and passes it to the view as a property. However, the property always comes through as nil, even when I verify using the debugger that the NSArray in the view controller is just fine.
View Controller
@interface GraphingViewController()
@property (nonatomic, weak) IBOutlet GraphingView *graphingView;
@end
- (void) determinePointsOnGraph
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *pointsForGraph = [[NSMutableArray alloc] init];
float startingPoint = -250;
for (int i = 0; i < 500; i++) {
float x = startingPoint;
startingPoint++;
[dict setValue:[NSNumber numberWithFloat:x] forKey:[NSString stringWithString:@"x"]];
float y = [CalculatorBrain runProgram:[self graph] usingVariableValues:dict];
[pointsForGraph addObject:[NSValue valueWithCGPoint:CGPointMake(x,y)]];
}
//This calls the pointer to the view, and the setter for the view's property
[self.graphingView setPointsOnGraph:pointsForGraph];
}
View
@synthesize pointsOnGraph = _pointsOnGraph;
- (void)setPointsOnGraph:(NSArray *)pointsOnGraph
{
//Custom setter for property, never gets called if a break point is put here
_pointsOnGraph = pointsOnGraph;
[self setNeedsDisplay];
}
- (void)drawLine:(NSArray *)pointsOfLine inContext:(CGContextRef)context
{
CGPoint pointsOfLineAsCGPoints[[pointsOfLine count]];
for (int i = 0; i < sizeof(pointsOfLineAsCGPoints); i++) {
pointsOfLineAsCGPoints[i] = [[pointsOfLine objectAtIndex:i] CGPointValue];
}
CGContextAddLines(context, pointsOfLineAsCGPoints, sizeof(pointsOfLine));
CGContextClosePath(context);
CGContextStrokePath(context);
}
The drawLine method is called by the drawRect and is passed the pointsOnGraph property as pointsOfLine. Even if I put a break point in the drawRect and look at the pointsOnGraph property it’s always nil in the view. However, when it is passed to the view by the view controller it contains hundreds of objects.
I just don’t understand why the property is always nil, and if I put a break point in the setter it never gets called.
Update
I have verified that the faceView reference to the view is nil when it is first called, but the IBOutlet appears to be hooked up properly, and the view eventually gets display. It seems that the view controller method is getting called before the self.graphingView IBOutlet is initialized
The Following is from the View Controller that I segue from
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"Graphing"] ) {
[segue.destinationViewController setGraph:[[self.brain program] mutableCopy]];
[segue.destinationViewController determinePointsOnGraph];
}
}
Solution
Call the determinePointsOnGraph method in the viewDidLoad delegate rather than in prepare for segue. This ensures that the view has been created. I also had another problem stemming from the fact that the outlet from the view to access the data in the view controller wasn’t initialized in the view setter.
Call determine points on graph in view delegate method viewDidLoad