简体   繁体   English

在View初始化之前调用的View Controller中的方法-iPhone iOS 5 SDK

[英]Method in View Controller Called before View initialized - iPhone iOS 5 SDK

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. 我有一个视图控制器,它创建一个NSValue对象的NSArray并将其作为属性传递给视图。 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. 但是,即使我使用调试器确认视图控制器中的NSArray正常,该属性也始终为nil。

View Controller @interface GraphingViewController() @property (nonatomic, weak) IBOutlet GraphingView *graphingView; 视图控制器 @interface GraphingViewController()@属性(非原子,弱)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. drawLine方法由drawRect调用,并将pointsOnGraph属性作为pointsOfLine传递。 Even if I put a break point in the drawRect and look at the pointsOnGraph property it's always nil in the view. 即使我在drawRect中放置一个断点并查看pointsOnGraph属性,它在视图中也始终为零。 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. 更新我已经验证了第一次调用该视图时,该视图的faceView引用为nil,但IBOutlet似乎已正确连接,该视图最终得到显示。 It seems that the view controller method is getting called before the self.graphingView IBOutlet is initialized 似乎在self.graphingView IBOutlet初始化之前就调用了视图控制器方法

The Following is from the View Controller that I segue from 以下是我从中选择的View Controller

- (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. 解决方案在viewDidLoad委托中而不是在准备segue时调用definePointsOnGraph方法。 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. 我还遇到另一个问题,这是因为在视图设置器中未初始化视图访问视图控制器中数据的出口。

调用setter之前,请确保self.graphingView不为nil

在视图委托方法viewDidLoad中调用图上的确定点

It seems like you are sending the message - (void)setPointsOnGraph:(NSArray *)pointsOnGraph too early before the self.graphingView gets initialized. 似乎您在初始化self.graphingView之前太早发送消息-(void)setPointsOnGraph:(NSArray *)pointsOnGraph

I would suggest that you send the message - (void) determinePointsOnGraph in viewWillAppear of the GraphingViewController. 我建议您发送消息-(无效) GraphingViewController的viewWillAppear中的definePointsOnGraph。 This is because your self.graphingView should be initialized (which should be done by the time -viewDidLoad gets called) before you set the NSArray pointsOnGraph. 这是因为在设置NSArray pointsOnGraph之前,应该对self.graphingView进行初始化(应在调用-viewDidLoad时完成)。

To confirm that my suggestion would work, please add your implementation of this GraphingViewController, especially the portion that calls the message - (void) determinePointsOnGraph . 为了确认我的建议是否可行,请添加您对此GraphingViewController的实现,尤其是调用消息的部分-(void)definePointsOnGraph

For your reference, when I get confused with views and the sequence of the methods, I input NSLogs in viewDidAppear, viewDidLoad, drawRect, and viewWillAppear to clarify what is happening. 供您参考,当我对视图和方法的顺序感到困惑时,我在viewDidAppear,viewDidLoad,drawRect和viewWillAppear中输入了NSLogs以阐明正在发生的事情。 The sequence should be viewDidLoad -> viewWillAppear -> drawRect -> viewDidAppear . 序列应为viewDidLoad-> viewWillAppear-> drawRect-> viewDidAppear

On another point, if your code works properly, your setter method in the graphingView will leak memory. 另一方面,如果您的代码正常运行,则graphingView中的setter方法将泄漏内存。 You need to release your _pointsOnGraph before you set it to the given pointer. 在将_pointsOnGraph设置为给定指针之前,需要释放它。 For example, you could implement it as follows: 例如,您可以按以下方式实现它:

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

plus, you should autorelease the NSArray before you send it with the message, for example: 另外,在发送消息之前,应自动释放NSArray,例如:

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

but better yet, you can reduce the amount of code and brackets by not alloc init'ing the NSMutableArray. 但更好的是,您可以通过不分配NSMutableArray来减少代码和括号的数量。 This can be done by changing 这可以通过更改来完成

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

to

NSMutableArray *pointsForGraph = [NSMutableArray dictionary];

and forget about the autorelease. 忘了自动发布。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iPhone SDK:在显示第一个视图控制器之前下载并设置UIImageView - iPhone SDK: Download and Set UIImageView before first view controller is displayed 从其他视图控制器调用方法。 iPhone SDK - Invoke a method from a different view controller. iPhone SDK 在单视图控制器中使用多视图控制器-iPhone SDK - Using Multiple view controller in single view controller - iPhone sdk 在查看Iphone SDK之前下载视频 - Download video before view Iphone sdk iPhone在ViewDidAppear之前弹出视图控制器 - iPhone Popping View Controller before ViewDidAppear iPhone视图控制器方法未调用但视图显示 - iphone view controller methods not being called but view shows 无法从Objective C,iPhone SDK中的另一个视图控制器调用方法 - Can not call method from another view controller in Objective C, iPhone SDK iPhone / iOS SDK:自动旋转主视图,而不是子视图? - iPhone/iOS SDK: Autorotate main view, but not child view? iPhone-在标签栏中切换视图控制器并调用方法 - iPhone - switching a view controller in the tabbar and call a method iOS-在加载视图控制器之前模拟UserDefault - iOS - Mocking UserDefault before loading the view controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM