1. 程式人生 > >Object-C(9)_代理(委託)設計模式

Object-C(9)_代理(委託)設計模式

代理(委託)設計模式

代理是指一個物件提供機會對另一個物件中的行為發生變化時作出的反應。代理設計模式的基本思想是兩個物件協同解決問題,通常用於物件之間的通訊。基本特點有:

  • 簡化了物件的行為,最小化了物件之間的耦合度
  • 使用代理,一般來說無需子類化
  • 簡化了應用程式的開發,既容易實現,又靈活

NSRunloop概念

NSRunloop就是一個事件處理的迴圈,用來不停的排程工作以及處理輸入事件。使用runloop的目的是讓你的執行緒在有工作的時候忙於工作,而沒工作的時候處於休眠狀態。在應用程式中,不需要建立NSRunloop物件。因為在主執行緒(包含其他子執行緒)系統中會自動建立NSRunloop

物件。如果你需要訪問當前執行緒中的runloop,可以通過類方法currentRunloop呼叫。

中介找房代理設計模式的實現

一、需求分析

  • 租客需要找房,委託中介人去找房
  • 中介人負責找房
  • 協議合同規定了租客與中介人的法律效益

二、程式碼實現 1、 建立租客Person

  • 建立Person.h類
#import <Foundation/Foundation.h>
#import "ApartmentProtocol.h" // 使用當前協議
@protocol PersinDelegate; // 協議的宣告,不宣告的話就要把協議寫在類前面 
@interface Person : NSObject
{
@private
    NSString *name;
    id <ApartmentProtocol> _delegate;
    id <PersinDelegate> _delegates;
}
@property (nonatomic,copy) NSString *name;
@property (nonatomic) id <ApartmentProtocol> _delegate; //assign防止迴圈引用
- (id)initWithName:(NSString *)name withDelegate: (id <ApartmentProtocol>) delegate;
- (void)personFindApartment;
@end
  • 建立Person.m實現類
#import "Person.h"

// 定義私有方法
@interface Person()
- (void) startFindApartment:(NSTimer *)timer;
@end
@implementation Person
@synthesize name,_delegate;
// 初始化租客姓名和中介
- (id) initWithName:(NSString *)name withDelegate: (id) delegate
{
    if (self == [super init]) {
        self.name = name;
        self._delegate = delegate;
    }
    return self; 
}
// 租客找房方法
- (void) personFindApartment
{
	// 使用定時器呼叫startFindApartment找房方法,startFindApartment內部方法,在實現類內部使用
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(startFindApartment:) userInfo:@"Tom" repeats:YES];
}

// 開始找房
- (void) startFindApartment:(NSTimer *)timer
{
    NSString *userInfo = [timer userInfo];
    NSLog(@"%@",userInfo);
    if ([self._delegate respondsToSelector:@selector(findApartment:)]) {
       HouseRent rent = [self._delegate findApartment:self];
        if (rent == HighRent) {
            NSLog(@"%@說太貴",self.name);
        } else if (rent == MiddleRent){
            NSLog(@"%@說價格合適",self.name);
        } else if (rent == LowRent){
            NSLog(@"%@說價格不錯,就要這套了",self.name);
            [timer invalidate]; // 停掉定時器
        } else if (rent == Finding){
            NSLog(@"%@說找到通知我",self.name);
        }
    }
}
@end

2、建立中介人Agent

  • 建立Agent.h
#import <Foundation/Foundation.h>
#import "ApartmentProtocol.h"
@interface Agent : NSObject <ApartmentProtocol> //實現ApartmentProtocol協議

@end
  • 建立Agent.m
#import "Agent.h"
#import "Person.h"
@implementation Agent

static int count = 3;
- (HouseRent)findApartment:(Person *) p;
{
    HouseRent rent;
   if(count == 1){
        rent = LowRent;
        NSLog(@"中介公司對%@說,找到一個價格較低的公寓",p.name);
       
    } else if(count == 2){
        rent = MiddleRent;
        NSLog(@"中介公司對%@說,找到一個價格合適的公寓",p.name);
    } else if(count == 3){
        rent = HighRent;
        NSLog(@"中介公司對%@說,找到一個價格較高的公寓",p.name);
    } else {
        NSLog(@"中介公司對%@說,正在找房",p.name);
        rent = Finding;
    }
    count --;
    return rent;
}
@end

3、 建立協議ApartmentProtocol

#import <Foundation/Foundation.h>
// 建立租金列舉
typedef enum {
    Finding = 0,
    LowRent = 1,
    MiddleRent = 2,
    HighRent = 3
    
} HouseRent;
@class Person; // 引入Person類,並不使用
@protocol ApartmentProtocol <NSObject>
@required
- (HouseRent)findApartment:(Person *) p;
@end

4、方法呼叫

#import <Foundation/Foundation.h>
#import "Agent.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
    	// 初始化中介
        Agent *agent = [[Agent alloc] init];
        // 初始化租客
        Person *tom = [[Person alloc] initWithName:@"tom" withDelegate: agent];
        // 呼叫租客找房方法
        [tom personFindApartment];
        BOOL isStop = YES;
        while (isStop) {
            NSDate *date = [NSDate date];
            // 6秒之後退出程式
            [[NSRunLoop currentRunLoop] runUntilDate:[date dateByAddingTimeInterval:6]];
            isStop = NO;
            NSLog(@"程式退出了 ");
        }
        // [[NSRunLoop currentRunLoop] run];
        
    }
    return 0;
}