Метод в контроллере представления, вызываемый перед инициализацией представления - iPhone iOS 5 SDK - PullRequest
0 голосов
/ 25 февраля 2012

По какой-то причине пользовательский установщик свойства никогда не вызывается. Так что во время выполнения он всегда приходит как ноль.

У меня есть контроллер представления, который создает NSArray объектов NSValue и передает его представлению как свойство. Однако свойство всегда указывается как nil, даже когда я проверяю с помощью отладчика, что NSArray в контроллере представления просто в порядке.

Просмотр контроллера @interface GraphingViewController () @property (неатомный, слабый) IBOutlet GraphingView * graphingView; @ Конец

- (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);
}

Метод drawLine вызывается drawRect и передается свойству pointsOnGraph в виде pointsOfLine. Даже если я поставлю точку останова в drawRect и посмотрю на свойство pointsOnGraph, оно всегда равно нулю в представлении. Однако когда он передается в представление контроллером представления, он содержит сотни объектов.

Я просто не понимаю, почему свойство всегда равно нулю, и если я ставлю точку останова в установщике, оно никогда не вызывается.

Обновление Я проверил, что ссылка faceView на представление является нулевой, когда он вызывается впервые, но IBOutlet, кажется, правильно подключен, и представление в конечном итоге получает отображение. Кажется, что метод контроллера представления вызывается до инициализации IB.utlet self.graphingView

Ниже приводится информация о контроллере вида, который я использую с

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"Graphing"] ) {
        [segue.destinationViewController setGraph:[[self.brain program] mutableCopy]]; 
        [segue.destinationViewController determinePointsOnGraph];

    }
}

Решение Вызывайте метод definePointsOnGraph в делегате viewDidLoad, а не в подготовке к переходу. Это гарантирует, что представление было создано. У меня также была другая проблема, связанная с тем, что выход из представления для доступа к данным в контроллере представления не был инициализирован в установщике представления.

Ответы [ 3 ]

0 голосов
/ 25 февраля 2012

Вызов определения точек на графе в представлении делегата, метода viewDidLoad

0 голосов
/ 25 февраля 2012

Похоже, вы отправляете сообщение - (void) setPointsOnGraph: (NSArray *) pointsOnGraph слишком рано до инициализации self.graphingView.

Я бы посоветовал вам отправитьсообщение - (void) definePointsOnGraph в viewWillAppear GraphingViewController.Это потому, что ваш self.graphingView должен быть инициализирован (что должно быть сделано к моменту вызова -viewDidLoad) до того, как вы установите NSArray pointsOnGraph.

Чтобы подтвердить, что мое предложение будет работать, добавьте вашу реализацию этогоGraphingViewController, особенно часть, которая вызывает сообщение - (void) definePointsOnGraph .

Для справки, когда я путаюсь с представлениями и последовательностью методов, я ввожу NSLogs в viewDidAppear,viewDidLoad, drawRect и viewWillAppear, чтобы уточнить, что происходит.Последовательность должна быть viewDidLoad -> viewWillAppear -> drawRect -> viewDidAppear .

В другой точке, если ваш код работает правильно, ваш метод установки в GraphingView будет просачиваться из памяти.Вам нужно освободить свой _pointsOnGraph перед тем, как установить его для указанного указателя.Например, вы можете реализовать его следующим образом:

- (void)setPointsOnGraph:(NSArray *)pointsOnGraph
{
    [_pointsOnGraph release];
    _pointsOnGraph = pointsOnGraph;
    [self setNeedsDisplay];
}

плюс, вы должны автоматически выпустить NSArray перед отправкой с сообщением, например:

[self.graphingView setPointsOnGraph:[pointsForGraph autorelease]];

, но еще лучше,Вы можете уменьшить количество кода и скобок, не выделяя init'ing NSMutableArray.Это можно сделать, изменив

NSMutableArray *pointsForGraph = [[NSMutableArray alloc] init];

на

NSMutableArray *pointsForGraph = [NSMutableArray dictionary];

и забудьте об автоматическом выпуске.

0 голосов
/ 25 февраля 2012

Убедитесь, что self.graphingView не ноль, прежде чем вызывать сеттер

...