Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is [foo view] behaving differently than foo.view in my code?

Purely by accident I discovered that calling [bar.view addSubview:[foo view]] doesn't work, but [bar.view addSubview:foo.view] does in the following code.

foo=[fooViewController alloc] initWithNibName:@"fooViewController" andBundle:nil];
[self.view addSubview:foo.view];//here's where I swap the two commands out
[foo aFunctionThatSendsAMessageToOneOfFoosSubViews];

(That last line is because foo has some sub-views that need to be set up prior to running -- notably, a UIWebView. If they haven't been instantiated before the message is sent, the message winds up going to nil. With foo.)

I thought these two were functionally identical -- that foo.view calls the same getter that [foo view] does, but in practice that's not the case; the dot syntax gets the desired results, while using the brackets winds up sending the message to nil.

If you'd asked me ten minutes ago, I would have told you the difference between the two expressions was 'syntax, and nothing else'. Given that I'm clearly wrong, I need to understand HOW I'm wrong or I'm going to stumble over it again.

like image 686
RonLugge Avatar asked Mar 28 '12 01:03

RonLugge


1 Answers

They are functionally equivalent. I think this is a race condition. When you first call foo.view in that code, the view is not loaded yet, and a call is sent to [foo loadView]. You can't be sure that the view is loaded until [foo viewDidLoad] is called or foo.isViewLoaded == YES.

You need to wait make sure the view is loaded before performing any actions that rely on it, such as [foo aFunctionThatSendsAMessageToOneOfFoosSubViews].

In your current case, sometimes it is loading in time and sometimes it isn't.

like image 175
rosslebeau Avatar answered Oct 07 '22 01:10

rosslebeau