簡體   English   中英

iPhone:朋友列表,Facebook是怎么做到的?

[英]iPhone : friend list, how did Facebook accomplished that?

我想知道是否有人可以推測或更好地提供一段代碼來實現 Facebook iPhone 應用程序中的冗長朋友列表。

當您打開應用程序和 go 海峽進入朋友列表時,您幾乎可以在瞬間獲得列表,至少對我有大約 500 個朋友來說。

當我在自己的應用程序中嘗試它時,需要花費大量寶貴的時間來使用相同的數據填充表格視圖,那么 Facebook 是如何實現如此快速的響應時間的呢?

在查看 facebook 應用程序中的表格視圖時,您會注意到此類表格視圖中通常沒有滾動條,這可能是 facebook 用於實現這種快速行插入的巧妙技巧的一個標志嗎? 難道他們實現了某種只包含幾十行但旋轉它們的虛擬表格視圖?

有什么想法嗎?

UITableView 會讓你這樣做。 互聯網上有許多示例,包括 UITableView 和自定義單元

本質上,您在后台加載圖像,並重用表格視圖中的單元格

編輯添加了示例代碼來演示這是如何完成的。
重要的提示
此代碼未經測試,實際上可能會或可能不會按原樣 function。
它粘貼了一些長度的編輯。 我在我的應用程序中做了更多的事情,但為了與所要求的示例保持一致,我省略了很多。

以示例為例:
這是我拿到單元格的地方,用現成的項目加載它。 並將其發送到后台線程以加載 rest。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"OfferCell";
    static NSString *CellNib = @"OfferItem";

    OfferCell* cell = (OfferCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
        cell = (OfferCell*)[nib objectAtIndex:0];
    }



    NSDictionary* couponPackage = [self.jsonOfferData valueForKey:@"result"];

    NSArray *couponList = [couponPackage valueForKey:@"offers"];

    if ([couponList count] >= indexPath.row )
    {
        NSDictionary* couponData = [couponList objectAtIndex:indexPath.row];
        Coupon *coupon = [[Coupon alloc] initWithDictionary:couponData];

        NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:cell,@"cell",coupon,@"coupon", nil];

        //Right here you would try to load any cached imaged from disk.

        //Then send a Thread to the background to load the image.
        [self performSelectorInBackground:@selector(loadTableViewCellData:) withObject:params];

        //Load up the rest of the custom info into the custom cell.
        [cell.captionLabel setText:coupon.name];
        [cell.subTextLabel setText:coupon.subText];
        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
        [cell setCommand:coupon.command];
        [cell setParameter:coupon.commandArgs];
        [cell setImageURL:coupon.imageURL];
        [cell setImageAltURL:coupon.imageAltURL];
        [cell setRegistrationCode:coupon.registrationCode];
        [coupon release];
    }    

    return cell;
}

如您所見,我什至在單元格中加載自定義內容之前調用了一個后台線程。

- (void) loadTableViewCellData:(NSDictionary*) objectData
{
    OfferCell *cell = [objectData objectForKey:@"cell"];
    Coupon *coupon = [objectData objectForKey:@"coupon"];
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[coupon iconURL]]]];
    [objectData setValue:image forKey:@"image"];
    self performSelectorOnMainThread:@selector(setImageOnMainThread:) withObject:objectData
}

下載圖像后,我發送主線程請求以更新單元格 object 中的圖像。

- (void) setImageOnMainThread:(NSDictionary*) objectData
{
    OfferCell *cell = [objectData objectForKey:@"cell"];
    Coupon *coupon = [objectData objectForKey:@"coupon"];
    UIImage *image = [objectData objectForKey:@"image"];
    cell.icon.image = image;
}

##AGAIN 這實際上可能不是 Function。 ##
我沒有為此復制所有代碼。 這是一個錘子,所以你可以得到這個想法。
玩代碼並測試它。 但基本面是。

  • 將滿足您需求的單元格出列(重用標識符)
  • 如果單元格可以出列或使用重用標識符創建一個新單元格,則使用該單元格(我的示例使用名為 OfferItem.xib 的 xib 文件)
  • 向后台發送線程,從磁盤或 url 加載圖像數據(推薦兩者結合)
  • 當您准備好將圖像加載到視圖中時,將線程發送回 UI(更新 UI 必須在主線程上完成)

如果你能做到這一點,那么你的朋友列表(或者在這種情況下提供)將盡可能快地加載。 並且圖像將在下載后立即出現在屏幕上。

此外,如果您使用緩存技術,后續加載會更快,因為在第一種方法 {tableView:cellForRowAtIndexPath:} 中,您將立即加載緩存的圖像。

除此之外,這應該會非常快地加載您的單元格。

他們顯然從本地資源(plist,ManagedObject,...)加載數據

看一些示例代碼來繪制 TableView:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellIdentifier = @"MyCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellIdentifier] autorelease];
}
return cell;
}

dequeueReusableCellWithIdentifier: 是 iOS 中的 TableViews 可以快速繪制的原因之一。 它以某種方式工作,如下所示:

1)您為正在創建的單元格提供標識符。

2)最初可見的單元格被分配(帶有標識符)

3)當一個單元格從屏幕上移開時,它會被放在一堆MyCellIdentifier

4) 每當系統需要繪制一個標識符為: MyCellIdentifier的單元格時,它首先查看MyCellIdentifier堆上是否有當前未使用的單元格。 如果是這種情況,它會從一堆中挑選一個,因此不必分配一個新的。 這樣可以將昂貴的分配保持在最低限度。

我希望這回答了你的問題:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM