Не вызывается метод загрузки TTModel

#cocoa-touch #ios #ios4 #three20

#cocoa-touch #iOS #ios4 #three20

Вопрос:

Проблема

Описание

Следующий код приводит к тому, что метод загрузки TTModel не вызывается. Я выполнил его через отладчик, а также пошагово через приложение TTCatalog. Единственное различие между ними, которое я вижу, заключается в том, что когда каталог устанавливает свой источник данных в методе CreateModel контроллера, метод загрузки TTModel вызывается, тогда как мой — нет.

О коде

Я прокомментировал конкретные области кода, чтобы рассказать, что они должны делать и какая проблема возникает, но я включил все это для завершения.

Вам следует обратить особое внимание

  • Метод CreateModel PositionsController от PositionsController
  • Метод загрузки PositionsList в

Это области, в которых возникает проблема, и было бы лучшим местом для начала.


Код

PositionsController: TTTableViewController

 - (id)initWIthNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        self.title = @"Positions";
        self.variableHeightRows = NO;
        self.navigationBarTintColor = [UIColor colorWithHexString:@"1F455E"];
    }

    return self;
}

//This method here should result in a call to the PositionsList load method
- (void)createModel
{
    PositionsDataSource *ds = [[PositionsDataSource alloc] init];
    self.dataSource = ds;
    [ds release];
}

- (void)loadView
{
    [super loadView];
    self.view = [[[UIView alloc] initWithFrame:TTApplicationFrame()] autorelease];
    self.tableView = [[[UITableView alloc] initWithFrame:TTApplicationFrame() style:UITableViewStylePlain] autorelease];
    self.tableView.backgroundColor = [UIColor colorWithHexString:@"E2E7ED"];
    self.tableView.separatorColor = [UIColor whiteColor];
    self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    //self.tableView.delegate = self;
    [self.view addSubview:self.tableView];
}

//Override UITableViewDelegate creation method, so we can add drag to refresh
- (id<TTTableViewDelegate>) createDelegate {

    TTTableViewDragRefreshDelegate *delegate = [[TTTableViewDragRefreshDelegate alloc] initWithController:self];

    return [delegate autorelease];
}
  

PositionsDataSource: TTListDataSource

 @implementation PositionsDataSource

@synthesize positionsList = _positionsList;

-(id)init
{
    if (self = [super init]) 
    {
        _positionsList = [[PositionsList alloc] init];
        self.model = _positionsList;
    }
    return self;
}

-(void)dealloc
{
    TT_RELEASE_SAFELY(_positionsList);
    [super dealloc];
}

-(void)tableViewDidLoadModel:(UITableView*)tableView
{
    self.items = [NSMutableArray array];
}

-(id<TTModel>)model
{
    return _positionsList;
}
@end
  

Список позиций: NSObject <TTModel >

 @implementation PositionsList

//============================================================
//NSObject

- (id)init
{
    if (self = [super init])
    {
        _delegates = nil;
        loaded = NO;
        client = [[Client alloc] init];
    }
    return self;
}

- (void)dealloc
{
    TT_RELEASE_SAFELY(_delegates);
    [client dealloc];
    [super dealloc];
}

//==============================================================
//TTModel

- (NSMutableArray*)delegates
{
    if (!_delegates)
    {
        _delegates = TTCreateNonRetainingArray();
    } 
    return _delegates;
}

-(BOOL)isLoadingMore
{
    return NO;
}

-(BOOL)isOutdated
{
    return NO;
}

-(BOOL)isLoaded
{
    return loaded;
}

-(BOOL)isEmpty
{
    //return !_positions.count;
    return NO;
}

-(BOOL)isLoading
{
    return YES;
}

-(void)cancel
{
}

//This method is never called, why is that?
-(void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more
{
    //This method is not getting called
    //When the PositionsController calls self.datasource, load should be called,
    //however it isn't.
    [_delegates perform:@selector(modelDidStartLoad:) withObject:self];
    [client writeToServer:self dataToSend:@""];
}

-(void)invalidate:(BOOL)erase
{
}

@end
  

Ответ №1:

Короткий ответ: верните NO вместо YES для isLoading в вашем списке позиций.

Для более подробного объяснения:

Если вы покопаетесь в источнике Three20, вы обнаружите, что установка источника данных на контроллере представления устанавливает модель, обновляя модель и потенциально вызывая load . Вот код, вызываемый при обновлении TTModelViewController:

 - (void)refresh {
  _flags.isViewInvalid = YES;
  _flags.isModelDidRefreshInvalid = YES;

  BOOL loading = self.model.isLoading;
  BOOL loaded = self.model.isLoaded;
  if (!loading amp;amp; !loaded amp;amp; [self shouldLoad]) {
    [self.model load:TTURLRequestCachePolicyDefault more:NO];

  } else if (!loading amp;amp; loaded amp;amp; [self shouldReload]) {
    [self.model load:TTURLRequestCachePolicyNetwork more:NO];

  } else if (!loading amp;amp; [self shouldLoadMore]) {
    [self.model load:TTURLRequestCachePolicyDefault more:YES];

  } else {
    _flags.isModelDidLoadInvalid = YES;
    if (_isViewAppearing) {
      [self updateView];
    }
  }
}
  

Ваш объект PositionList возвращает YES для isLoading и NO для isLoaded. Это означает, что Three20 считает, что ваша модель загружается, хотя это не так. Вам также может потребоваться реализовать shouldLoad, если он не возвращает YES по умолчанию.

Комментарии:

1. Идеально! Для справки в будущем, где вы искали? Каждый раз, когда я пытаюсь просмотреть исходный код, я в конечном итоге просто вижу, что представляет собой файл заголовка, даже если это реализация.