2013-06-20 76 views
0

我有一個段和一個表視圖,我不得不重新加載數據在表視圖中的工作,但是當我切換段按鈕快,然後應用程序崩潰。應用程序崩潰快速切換UISegment

在段上我有三個按鈕和他們的動作,我觸發一個URL的請求,並從該URL獲取JSON(3個不同的URL並返回10,17和8結果在JSON中)。

我有一個自定義表格單元格中有圖像,我想懶惰地加載這些圖像。

在JSON結果JSON的每個對象在它的各種按鍵,如姓名,身份證,IMAGEURL等

的ID是整個應用程序的獨特,我試圖加載圖像,並保存在本地存儲器中的影像基於這個唯一的ID,這樣我就可以顯示兌現的圖像,並且不需要重新下載片段更改中的圖像,因爲所有三個片段上的某些輸入相同。

這裏是我完整的代碼

- (IBAction)segmentedControlIndexChanged { 
NSString *offerRequestUrl = nil; 
switch (self.mySegment.selectedSegmentIndex) { 
    case 0: 
     offerRequestUrl = @"url_one"; 
     self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl]; 
     break; 
    case 1: 
     offerRequestUrl = @"url_two";; 
     self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl]; 
     break; 
    case 2: 
     offerRequestUrl = @"url_three";; 
     self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl]; 
     break; 

    default: 
     break; 
} 
    [self parseJSONWithURL:self.feedRequestUrl]; 
} 
- (void) parseJSONWithURL:(NSURL *) jsonURL 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSData* data = [NSData dataWithContentsOfURL: jsonURL]; 
     [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES]; 
    }); 
} 

- (void)fetchedData:(NSData *)responseData { 
//parse out the json data 
NSError* error; 
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData 
                options:kNilOptions 
                 error:&error]; 

self.feedsArray = [json objectForKey:@"result"]; 
[self.myTableView reloadData]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
int count = self.feedsArray.count; 

// if there's no data yet, return enough rows to fill the screen 
if (count == 0) 
{ 
    return 1; 
} 
return count; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

// customize the appearance of table view cells 
// 
static NSString *CellIdentifier = @"MyTableCell"; 
static NSString *PlaceholderCellIdentifier = @"PlaceholderCell"; 

// add a placeholder cell while waiting on table data 
int nodeCount = [self.feedsArray count]; 

if (nodeCount == 0 && indexPath.row == 0) 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier]; 

    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
             reuseIdentifier:PlaceholderCellIdentifier]; 
     cell.detailTextLabel.textAlignment = UITextAlignmentCenter; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    cell.detailTextLabel.text = @"Loading . . ."; 

    [self performSelector:@selector(checkAndDisplayAlert) withObject:self afterDelay:10.0]; 

    return cell; 
} 

CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (nodeCount > 0) 
{   
    // Configure the cell... 
    cell.carImageView.image = [UIImage imageNamed:@"Placeholder"]; //acts as default image 
    if([self.imageDict valueForKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]==nil) 
    { 
     [NSThread detachNewThreadSelector:@selector(displayingSmallImage:) toTarget:self withObject:indexPath]; 
    } else { 
     cell.carImageView.image = [self.imageDict valueForKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]; 
    } 

    cell.imageView.clipsToBounds = YES; 
    cell.titleLabel.text = self.feedsArray[indexPath.row][@"title_key"]; 

} 
return cell; 
} 

    - (void) displayingSmallImage:(NSIndexPath *)indexPath 
{ 
NSString *imageUrl = self.feedsArray[indexPath.row][@"icon_url"]; 

NSURL *url = [NSURL URLWithString:imageUrl]; 
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; 
if(image == nil) 
{ 
    image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Placeholder"]]; 
} 
[self.imageDict setObject:image forKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]; 
[self performSelectorOnMainThread:@selector(imageReceived:) withObject:indexPath waitUntilDone:NO]; 
    } 

    - (void) imageReceived:(NSIndexPath *)indexPath 
{ 
UIImage *image = (UIImage *)[self.imageDict objectForKey: [NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]; 
UIImageView *imgs = (UIImageView *)[[self.myTableView cellForRowAtIndexPath:indexPath] viewWithTag:IMG_TAG]; 
[imgs setImage:image]; 
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; 
    } 

    - (void) checkAndDisplayAlert 
{ 
if (!self.feedsArray && self.isAlertPresent == NO) { 
    UIAlertView *nilAlert = [[UIAlertView alloc] initWithTitle:@"Sorry!" 
                 message:@"No result returned from server." 
                 delegate:self 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 
    [nilAlert setTag:kNilAlertTag]; 
    self.isAlertPresent = YES; 
    [nilAlert show]; 
} 
} 

我必須做的主要事情是

  1. 懶洋洋地下載圖像

  2. 緩存在本地存儲器中的影像以獨特的ID

  3. 查看兌現的圖片字幕元對已經下載並顯示圖像

  4. 如果可能保存在本地存儲這些下載的圖片(NSUserDefaults的等),因此如果用戶重新啓動應用程序,然後還影像在那裏,可以基於其獨特的ID和不顯示需要再次下載。

任何幫助,將不勝感激。

+0

也許我沒有完全以下......不是四「你所要做的主要的東西」正是你需要完成你的目標(S)是什麼?你有沒有試圖實現這些呢? – Dan

+0

是的,我正在嘗試前三名,但應用程序崩潰。 –

+0

小心分享崩潰的地方嗎?在旁邊注意一個超級懶惰的方法來禁用UITabBar按鈕,直到初始加載完成。這樣,當你開始思考#4時,你很好走。再一次...這是純粹的繃帶。 – Dan

回答

0

請張貼錯誤日誌,如果是數組越界例外的,我懷疑這兩種方法

- (void)fetchedData:(NSData *)responseData & your tableViewDatasource 

要找出哪一行代碼導致該崩潰做到這一點。轉到左側的中斷點標籤並點擊底部的+。

enter image description here

,那麼你會得到這樣的:

enter image description here

剛打後,再次運行代碼,並告訴我們哪一行導致異常。

我明白你的問題,你爲什麼要採取從數組中的URL在這個函數

- (void) displayingSmallImage:(NSIndexPath *)indexPath 

,你可以通過URL來加載到功能,從cellForRowAtIndex這樣的:

NSArray *argsToPass=[NSArray arrayWithObjects:indexPath,self.feedsArray[indexPath.row][@"icon_url"]]; 

    [NSThread detachNewThreadSelector:@selector(displayingSmallImage:) toTarget:self withObject:argsToPass]; 

和你的函數修改爲:

- (void) displayingSmallImage:(NSArray *)args 
{ 

    if([args count] == 0) 
{ 
NSString *imageUrl = [args objectAtIndex:1]; 

NSIndexPath *indexPath=[args objectAtIndex:0]; 

NSURL *url = [NSURL URLWithString:imageUrl]; 
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; 
if(image == nil) 
{ 
    image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Placeholder"]]; 
} 
[self.imageDict setObject:image forKey:[NSString stringWithFormat:@"%@", self.feedsArray[indexPath.row][@"id_str"]]]; 
[self performSelectorOnMainThread:@selector(imageReceived:) withObject:indexPath waitUntilDone:NO]; 
    } 
} 
+0

謝謝,我會按照這個方法,並在一段時間 –

+0

控制是共享的結果 - (空隙)displayingSmallImage:(NSIndexPath *)indexPath 方法和在線[self.imageDict的setObject:圖像forKey:的NSString stringWithFormat:@ 「%@」,self.feedsArray [indexPath.row] [@ 「ID_STR」]]] ; 呈現出sigabert錯誤 –

+0

從你的代碼,說你是在試圖訪問從字典正確的陣列的字典?我想問題是你的self.feedsArray,它不包含在傳遞的索引對象。 – satheeshwaran

0

你可以設置self.view.u當您向服務器發送請求時,serInteractionEnabled = NO。 當你得到數據只是啓用用戶交互,以避免多個請求。

相關問題