3

I know that if map a url with from:toViewController:, then open that url will create a new view controller and if from:toSharedViewController is used then a shared instance will be used.

But for example

 [map from:@"tt://tabbar/(initWithString:)" toSharedViewController:[MyTabbarController class]];
 TTOpenURL(@"tt://tabbar/string");

This will invoke something similar to

 [[MyTabbarController alloc] initWithString:@"string"]

But what will be happened if TTOpenURL(@"tt://tabbar/somethingelse") in called later? Since a shared object is used so will the initWithString: be called twice on a same instance?

Bryan Chen
  • 45,816
  • 18
  • 112
  • 143

1 Answers1

2

The answer is : no. I.e., init will not be called on an already initialized instance, but a new instance will be allocated and initialized.

This is due to Three20 associating the object to its full URL, which in your case is either "tt://tabbar/string" or "tt://tabbar/somethingelse", so that when querying the TTURLMap, no already existing object will be found and a new one will be instantiated. At least, this is true as of Three20 1.0.3. But I guess they have not changed this.

In my opinion, the shared controller mechanism is to be used in very specific cases, like for a setting view, and it should not be thought as a sort of Three20-implemented singleton. Each time I tried to rely on this for more "clever" usage of the TTURLMap, I found myself going back to a non shared controller.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • Is possible to open a same instance and call a setter such as `setString:` not `initWithString:`? Otherwise it is almost not possible to reuse a controller. I found `from:toViewController:selector` but I am not sure how to use it – Bryan Chen Jun 06 '11 at 11:23
  • 1
    You can do that. Instead of calling `TTOpenURL`, you can also use `[[TTNavigator navigator] viewControllerForURL:@"xxxx"]` if you just want to get the existing controller. – sergio Jun 06 '11 at 11:27