toSharedViewController not re-using existing controller
Asked Answered
C

2

8

My URL map is as follows:

[map from:@"tt://webPage/(initWithPage:)" toSharedViewController:[WebPageController class]];

and in the WebPageController

- (id) initWithPage:(WebPage)page
{
    if (self = [super init])
    {
    ...

Then I called the url several times in my code

tt://webPage/1
tt://webPage/2
tt://webPage/1 (still called the initWithPage: everytime, not cached)

Why it is not cached as it is a SharedViewController?

Cook answered 12/2, 2012 at 3:31 Comment(2)
What is WebPage typedefed to?Vacillatory
@tonklon, it is just a random ENUMCook
D
4

I believe this is happening to you because TTNaviagtor is broken on iOS 5. see https://github.com/facebook/three20/pull/719/files. Have you tried running the same code on a iOS 4 with the same result?

My recommendation to you is to stop using TTNaviagtor. You can still use the three20 library by pushing and poping TTViewController in the native ios method.

Here's an example on replacing the TTNaviagtor in your app delegate:

@interface AppDelegate : NSObject <UIApplicationDelegate> {

 UIWindow* _window;
 TTBaseNavigationController* _masterNavController;
 WebPageController* _web1Controller;
 WebPageController* _web2Controller;
}

@property(nonatomic, retain) UIWindow* window;
@property(nonatomic, retain) TTBaseNavigationController* masterNavController;
@property(nonatomic, retain) WebPageController* web1Controller;
@property(nonatomic, retain) WebPageController* web2Controller;

And

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation AppDelegate

@synthesize window = _window;

@synthesize masterNavController = _masterNavController;
@synthesize web1Controller = _web1Controller;
@synthesize web2Controller = web2Controller;

///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  _window = [[UIWindow alloc] initWithFrame:TTScreenBounds()];


    TTViewController* controller = [[[MasterViewController alloc] init] autorelease];
    _masterNavController = [[TTBaseNavigationController alloc] initWithRootViewController:controller];
    [_window addSubview:_masterNavController.view];    
  }

  [_window makeKeyAndVisible];

  return YES;
}

then you can push and pop any TTViewController (or your own subclasses of TTViewController) into the _masterNavController. Personally, i think TTNavigator is a bad design pattern, and apple designed their navigation system in different mindset.

Diphenyl answered 17/2, 2012 at 18:2 Comment(0)
M
0

why not step into the code and check what happen?

I believe the objects are created in TTURLMap's objectForURL:query:pattern: you can set a break point and see why a new one is created instead re-use old one.

this the implementation of objectForURL:query:pattern: with my comment

- (id)objectForURL: (NSString*)URL
             query: (NSDictionary*)query
           pattern: (TTURLNavigatorPattern**)outPattern {
  id object = nil;
  if (_objectMappings) {
    // _objectMappings is a NSMutableDictionary and use to cache shared object
    object = [_objectMappings objectForKey:URL]; 
    // if object not found than check does _objectMappings contains it with right key
    if (object && !outPattern) {
      return object;
    }
  }

  NSURL* theURL = [NSURL URLWithString:URL];
  TTURLNavigatorPattern* pattern  = [self matchObjectPattern:theURL];
  if (pattern) {
    if (!object) {
      // object is not found in the mapping dictionary so create new one, this should only happen once for shared object
      object = [pattern createObjectFromURL:theURL query:query]; 
    }
    // make sure navigationMode is TTNavigationModeShare
    if (pattern.navigationMode == TTNavigationModeShare && object) {
       // cache shared object in the mapping dictionary so next time it will re-use the cached one
      [self setObject:object forURL:URL];
      // if setObject:forURL: is not working than the shared object will not be cached
    }
    if (outPattern) {
      *outPattern = pattern;
    }
    return object;

  } else {
    return nil;
  }
}
Moneywort answered 22/2, 2012 at 3:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.