#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. Идеально! Для справки в будущем, где вы искали? Каждый раз, когда я пытаюсь просмотреть исходный код, я в конечном итоге просто вижу, что представляет собой файл заголовка, даже если это реализация.