Losing properties on viewDidLoad in Objective C

2019-08-10 07:33发布

I'm trying to build a simple App where users can choose a video from a tableViewController, which then loads a view that plays a video. My problem is transferring the URL of the video from the tableViewController to the viewController.

I followed this tutorial, and I am now trying to adapt the code to play videos instead of just show images

I am creating a viewController from a tableViewController like this:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    wwfpViewController * DVC = [[wwfpViewController alloc] init];
    NSIndexPath * path = [self.tableView indexPathForSelectedRow];
    NSString * theVideoName = [videoNames objectAtIndex:path.row];
    NSString * theVideoURL = [videoList objectAtIndex:path.row];
    DVC.videoNum = path.row;
    DVC.videoName = theVideoName;
    DVC.videoURL = theVideoURL;
    [DVC play];
}

The play message for this viewController is then fired, and when I NSLog from this message the videoURL is present and correct.

Then viewDidLoad is fired on this viewController, and at this point when I NSLog the videoURL it is returned as (null).

I'm declaring the videoURL like this:

@property (strong, nonatomic) NSString * videoURL;

So I have a few questions:

  • Does a viewController lose its properties when viewDidLoad is fired?
  • Is there a better approach to sending properties to a viewController?
  • Am I doing this completely wrong?
  • And do I need to provide any more code?

2条回答
姐就是有狂的资本
2楼-- · 2019-08-10 08:19

The problem is that despite the fact that you're using segues, you manually alloc/init a controller and set its properties (which of course is a totally different instance from the one that will be presented).

Here is what you should do instead:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Grab the destination controller
    // (it will be instantiated from the Storyboard automatically)
    wwfpViewController * DVC = (wwfpViewController *)segue.destinationViewController;
    NSIndexPath * path = [self.tableView indexPathForSelectedRow];
    NSString * theVideoName = [videoNames objectAtIndex:path.row];
    NSString * theVideoURL = [videoList objectAtIndex:path.row];
    // Set the properties
    DVC.videoNum = path.row;
    DVC.videoName = theVideoName;
    DVC.videoURL = theVideoURL;
    [DVC play]; // Why don't you call this on viewDidLoad of the destination controller?
}

PS: In Objective-C you usually name the ivars (by convention) so that they start with a small letter and the Classes with a capital one. So WWFPViewController and dvc would be more appropriate names in your case.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-08-10 08:29

You are mistakenly initializing and configuring new controller instance, which is released once the - (void)prepareForSegue: method ends and is never actually used. Another controller instance is automatically initilized by segue and then presented. That is the reason you see "null", its not really configured.

If you are using segues, you must configure destination view controller provided by UIStoryboardSegue instance instead of creating new one.

Something like this:

wwfpViewController * DVC = (wwfpViewController *)segue.destinationViewController;
查看更多
登录 后发表回答