未调用 TTModel 加载方法

Posted

技术标签:

【中文标题】未调用 TTModel 加载方法【英文标题】:TTModel load method not being called 【发布时间】:2011-05-15 19:21:24 【问题描述】:

问题

说明

以下代码导致 TTModelload 方法未被调用。我已经通过调试器单步调试它,以及单步调试 TTCatalog 应用程序。我可以看到两者之间的唯一区别是,当目录在控制器的 createModel 方法中设置它的 DataSource 时,会调用 TTModel 的 load 方法,而我的会调用不是。

关于代码

我已经对代码的特定区域进行了注释,以说明他们应该做什么以及正在发生什么问题,但为了完成,我将所有这些都包括在内。

你应该具体看

PositionsController 的 createModel 方法 PositionsList 的 load 方法

这些是问题所在,也是最好的起点。


代码

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

PositionsList : NSObject &lt;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】:

简答:在 PositionList 中为 isLoading 返回 NO 而不是 YES

更详细的解释:

如果您深入研究 Three20 源代码,您会发现在视图控制器上设置 dataSource 会设置模型、刷新模型并可能调用 load。下面是 TTModelViewController 刷新时调用的代码:

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

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

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

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

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

您的 PositionList 对象为 isLoading 返回 YES,为 isLoaded 返回 NO。这意味着 Three20 认为您的模型正在加载,而实际上并非如此。如果默认情况下不返回 YES,您可能还需要实现 shouldLoad。

【讨论】:

完美!供将来参考您在哪里寻找?每次我尝试查看源代码时,我最终只会看到相当于头文件的内容,即使它是实现。

以上是关于未调用 TTModel 加载方法的主要内容,如果未能解决你的问题,请参考以下文章

iOS:首次加载时未调用 iCarousel 委托方法

重新加载数据后未调用 UICollectionView 数据源方法

未完全加载单元格时未调用 didSelectItemAtIndexPath

iPhone 抖动问题:加载 viewController 时未调用 viewDidAppear

在 iOS 8 中重新加载时未调用 UICollectionview cellForItemAtIndexPath

iOS 5:第一次加载控制器时未调用 willRotateToInterfaceOrientation:duration