IOS設計模式第五篇之裝飾設計模式的代理設計模式


版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

代理:

另一個裝飾設計模式,代理,是一個代表或者協調另一個對象的行為機制。例如當你用一個tableView,你必須實現他里面的一個tableView:numberOfRowsInSection:.方法。你不希望tableView知道他有多少行在每個section,因此這個計算每個區有幾行的任務交給了UITableView的代理。他允許tableView類是獨立的數據顯示。

當你創建一個UITableView的時候下面發生的:

Image

這個tableView的對象的工作是用來展示tableView的,然而最終他將需要一些信息他沒有的。然后轉向他的代理和要求額外的信息通過發送一條信息。在Objective-c實現代理的設計模式。一個類可以定義可選或者必須的方法通過協議。

你可能想生成一個對象的子類更容易並覆蓋必須的方法,但考慮到你只能基於單個類的子類。如果你想讓一個物體是兩個或者兩個以上的其他的對象的代表。你不能通過子類來實現這一目標。

注意:這是一個重要的設計模式。蘋果在UIKit類里面用到了很多。 UITableView,UITextView, UITextField, UIWebView, UIAlert, UIActionSheet, UICollectionView, UIPickerView,UIGestureRecognizer, UIScrollView.這里面都有

怎么使用代理的設計模式呢?

在Viewcontroller的實現文件里面導入頭文件:

#import "LibraryAPI.h"#import "Album+TableRepresentation.h"

現在添加一個延展來添加私有變量:

@interface ViewController () {

    UITableView *dataTable;

NSArray *allAlbums;

NSDictionary *currentAlbumData;

    int currentAlbumIndex;

}

@end

然后在延展的括號后面添加協議名字:

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

這使你的代理符合一個協議,使你能使用協議里面的方法。在這里你表示你的ViewController符合UITableViewDataSource 和UITableViewDelegate 協議。這種方法tableView可以絕對肯定的由其委托實現他協議必須實現的方法。

接下來在viewDidLoad寫以下代碼:

- (void)viewDidLoad

{

    [super viewDidLoad];

// 1

    self.view.backgroundColor = [UIColor colorWithRed:0.76f green:0.81f blue:0.87f alpha:1];

    currentAlbumIndex = 0;

//2

    allAlbums = [[LibraryAPI sharedInstance] getAlbums];

// 3

// the uitableview that presents the album data

    dataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 120, self.view.frame.size.width, self.view.frame.size.height-120) style:UITableViewStyleGrouped];

    dataTable.delegate = self;

    dataTable.dataSource = self;

    dataTable.backgroundView = nil;

    [self.view addSubview:dataTable];

}

對上面代碼的解釋:

1:改變背景顏色

2:得到專輯的列表用API而不是直接用PersistencyManager

3:這里創建tableView。你聲明這個ViewController是是tableView的代理或者數據源,因此tableView所有的信息都將要被這個Viewcontroller提供。

現在添加下面方法到Viewcontroller的實現文件里面

- (void)showDataForAlbumAtIndex:(int)albumIndex

{

// defensive code: make sure the requested index is lower than the amount of albums

    if (albumIndex < allAlbums.count)

    {

// fetch the album

        Album *album = allAlbums[albumIndex];

// save the albums data to present it later in the tableview

        currentAlbumData = [album tr_tableRepresentation];

    }

    else

    {

        currentAlbumData = nil;

    }

// we have the data we need, let's refresh our tableview

    [dataTable reloadData];

}

showDataForAlbumAtIndex從專輯的數組得到想要的專輯數據。當你想顯示最新的數據的時候你需要調用reloadData。他是tableView想他的代理詢問例如有多少section應該出現在tableVeiw上,在每個section里面有很多行,並且每行應該怎么顯示。

在ViewDidLoad最后一行添加[self showDataForAlbumAtIndex:currentAlbumIndex]

;

在應用加載當前專輯。並且currentAlbumIndex 先前設置0,他在集合里面展示第一個專輯。

編譯運行項目你得到一個崩潰下面有一個異常在debug窗口:

Image(1)

你把Viewcontroller設置為tableView的數據源或者代理。你必須實現他里面所有的必須實現的方法包括tableView:numberOfRowsInSection:但是你沒有這樣做。

在實現文件里面添加以下代碼:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return [currentAlbumData[@"titles"] count];

}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if (!cell)

    {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"];

    }

    cell.textLabel.text = currentAlbumData[@"titles"][indexPath.row];

    cell.detailTextLabel.text = currentAlbumData[@"values"][indexPath.row];

    return cell;

}

tableView:numberOfRowsInSection: 返回在tableView里面顯示多少行。和在數據結構里面標題的個數匹配、

tableView:cellForRowAtIndexPath:創建返回一個cell帶有標題和值;

編譯運行項目你的應用應該這樣展示:

Image(2)

到目前為止看起來不錯。但是如果你還記得完成應用后第一次啟動的畫面。在屏幕的頂部有一個水平照片的滑動視圖。而不是專用的水平滑動的視圖為什么不使他重用呢?

為了讓他重用,所有內容的顯示等都交給了另一個對象:一個代理。這個水平滑動視圖應該聲明協議方法讓他的代理來實現。類似於tableView的代理方法是怎么工作的。我們在下一個設計模式里面討論如何實現。

一個適配器設計模式允許你的類和不兼容的接口一起工作。它封裝在一個對象,並公開了一個標准的接口和該對象進行交互。如果你熟悉適配器設計模式,那么你會發現蘋果實現了它以稍微不同的方式--蘋果使用協議來做這項工作。你可能熟悉的協議像UITableViewDelegate,UScrollViewDelegate,NSCoding,和NSCopying。例如用這個NSCopying協議任何類可以提供標准的copy方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM