// DBRequestModel * someModel = [[DBRequestModel alloc] initWithQuery:@"SELECT * FROM TABLE USERS"]; // [someModel load:TTURLRequestCachePolicyNone more:NO]; // while ([someModel isLoading]) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } if ([someModel isLoaded]) { // result DBRequestModel // NSArray * users = [someModel result]; } else { // ? }
Why should we follow the change in the state of the model? In order to know when it will be relevant data.
[[someModel delegates] addObject:self];
- (void)showModelDataIfPossible { // self.model = [[DBRequestModel alloc] initWithQuery:@"SELECT * FROM TABLE USERS"]; // [[[self model] delegates] addObject:self]; // , // if (! [[self model] isLoaded] && [[self model] isOutdated]) { // [someModel load:TTURLRequestCachePolicyNone more:NO]; } else { // , // [self showModelData:[self model]]; } } #pragma mark - TTModelDelegate - (void)modelDidStartLoad:(id<TTModel>)model { // .. // [self showLoading]; } - (void)modelDidFinishLoad:(id<TTModel>)model { // [self hideLoading]; // // [self showModelData:[self model]]; } - (void)model:(id<TTModel>)model didFailLoadWithError:(NSError*)error { // [self hideLoading]; // User-Friendly TTAlertNoTitle(@"Error code #10"); // User-Friendly [self showReloadScreen]; self.reloadLabel.title = @"Something went wrong" "But you could try to reload data"; } - (void)modelDidCancelLoad:(id<TTModel>)model { // [self hideLoading]; // , // // , // } - (void)showModelData:(id<TTModel>)model { // result DBRequestModel // NSArray * users = [someModel result]; // [self showUsers:users]; }
The delegates array in TTModel is a special array that does not retain objects when they are added. It is created using the TTCreateNonRetainingArray function.
This is done to avoid circular references, and to comply with the convention that the delegate should not be retaine'd .
@interface ItemsListModel : TTURLRequestModel { /* */ NSMutableArray * _items; /* URL */ NSString * _baseURLString; /* */ int _page; /* */ int _itemsOnPage; } @property(nonatomic, readonly) NSMutableArray * users; @property(nonatomic, readonly) NSString * baseURLString; @property(nonatomic, assign) int page; @property(nonatomic, readonly) int itemsOnPage; /* c URL' */ - (id)initWithBaseURLString:(NSString *)baseURLString itemsOnPage:(int)itemsOnPage; /* , TTURLRequest */ - (TTURLRequest *)requestForDataWithCachePolicy:(TTURLRequestCachePolicy)cachePolicy more:(BOOL) more; /* , NSData * data */ - (NSArray *)parseDataToItems:(NSData *)data error:(NSError **)error; @end
@implementation ItemsListModel @synthesize items = _items; @synthesize itemsOnPage = _itemsOnPage; @synthesize baseURLString = _baseURLString; @synthesize page = _page; /* . . 0 */ - (id)initWithBaseURLString:(NSString *)baseURLString itemsOnPage:(int)itemsOnPage { self = [super init]; if (self) { _baseURLString = [baseURLString copy]; _itemsOnPage = itemsOnPage; _page = 0; _items = [[NSMutableArray array] retain]; _itemsOnPage = 20; } return self; } /* */ - (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more { // , , // if ( ! [self isLoading]) { // _isLoadingMore = more; // // if ( ! more) { [self reset]; } // TT_RELEASE_SAFELY(_loadingRequest); _loadingRequest = [[self requestForDataWithCachePolicy:cachePolicy more:more] retain]; // [_loadingRequest send]; } } /* , */ - (TTURLRequest *)requestForDataWithCachePolicy:(TTURLRequestCachePolicy)cachePolicy more:(BOOL) more { // // page // hhtp://baseURL/sdfsd?page=0 // // // NSString * fullRequestURL = self.baseURLString; fullRequestURL = [fullRequestURL stringByAddingQueryDictionary: [NSDictionary dictionaryWithObject: [NSString stringWithFormat:@"%d", _page] forKey:@"page" ] ]; // TTURLRequest * req = [TTURLRequest requestWithURL:fullRequestURL delegate:self]; req.cachePolicy = cachePolicy; req.response = [[TTURLDataResponse new] autorelease]; return req; } /* , */ - (NSArray *)parseDataToItems:(NSData *)data error:(NSError **)error { NSString * dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; // SBJSON NSArray * tweets = [dataString JSONValue]; return tweets; } - (void)requestDidFinishLoad:(TTURLRequest *)request { TTURLDataResponse * response = nil; // , if ([[request response] isKindOfClass:[TTURLDataResponse class]]) { response = (TTURLDataResponse *)request.response; } if ( ! response) { // - [self request:request didFailLoadWithError:nil/* */]; _isLoadingMore = NO; return; } NSError * error = nil; // , NSArray * loadedItems = [self parseDataToItems:[response data] error:&error]; // , if (error) { // ? [self request:request didFailLoadWithError:error]; return; } // , // if ([self isLoadingMore]) { [_items addObjectsFromArray:loadedItems]; } else { TT_RELEASE_SAFELY(_items); _items = [[NSMutableArray arrayWithArray:loadedItems] retain]; } // _page++; if ([loadedItems count] < _itemsOnPage) { /* , , */ // _hasMoreItems = NO } _isLoadingMore = NO; [super requestDidFinishLoad:request]; } /* */ - (void)reset { _page = 0; TT_RELEASE_SAFELY(_items); [super reset]; } /* */ - (void)dealloc { TT_RELEASE_SAFELY(_baseURLString); TT_RELEASE_SAFELY(_items); [super dealloc]; } @end
@implementation MyModelViewController #pragma mark - View LifeCycle - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self createAndStartModelIfNeeded]; } //... #pragma mark - Model Showing - (void)showModelData:(id<TTModel>)model { // result ItemsListModel // NSArray * tweets = [(ItemsListModel *)model items]; // " " NSLog(@"tweets : %{} ", tweets); // :( // @"tweets : %@" // - status Label if ([tweets count]) { NSDictionary * firstTweet = [tweets objectAtIndex:0]; NSString * tweetText = [firstTweet objectForKey:@"text"]; _statusLabel.text = [[_statusLabel text] stringByAppendingFormat:@"\n%@", tweetText]; } } #pragma mark - Model Creationg - (void)createAndStartModelIfNeeded { // if ( ! _model) { _model = [[ItemsListModel alloc] initWithBaseURLString:@"http://api.twitter.com/1/statuses/user_timeline.json?user_id=18191307" itemsOnPage:20]; [[_model delegates] addObject:self]; } // - if ( ! [_model isLoaded] ) { [_model load:TTURLRequestCachePolicyNone more:NO]; } } #pragma mark - TTModel Delegate - (void)modelDidStartLoad:(id<TTModel>)model { _statusLabel.text = @""; } - (void)modelDidFinishLoad:(id<TTModel>)model { _statusLabel.text = @"! "; [self showModelData:model]; } - (void)model:(id<TTModel>)model didFailLoadWithError:(NSError*)error { _statusLabel.text = [NSString stringWithFormat:@":(( %@", [error localizedDescription]]; } - (void)modelDidCancelLoad:(id<TTModel>)model { _statusLabel.text = @" "; } @end
Source: https://habr.com/ru/post/134821/