封裝(一)

     一個IOS中的自定義控件,每每是一個UIView的子類,可以獨立自主的完成一個特定功能。安全

     可以稱爲控件,意味着它是由多個基本控件和控制方法組合在一塊兒,咱們默認爲它的內部複雜且精密,經不起任何意外的變更。ide

    把它當作是一個黑盒子,咱們只考慮它的輸入是什麼,輸出是什麼。atom

     咱們來看一個最簡單的封裝例子spa

#import <UIKit/UIKit.h>

@protocol MyControlViewDelegate <NSObject>

@optional
- (void)myButtonTouched;

@end

@interface MyControlView : UIView

@property (nonatomic, weak) id<MyControlViewDelegate> delegate;

@end



#import "MyControlView.h"


@interface MyControlView()



@property (nonatomic, strong) UIButton *myButton;


@end

@implementation MyControlView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        [self setupInterface];

    }
    return self;
}

- (void)setupInterface
{
    self.myButton = [UIButton buttonWithType:UIButtonTypeCustom];
   self.myButton.frame = CGRectMake(50, 50, 200, 50);
    [self.myButton setTitle:@"testButton" forState:UIControlStateNormal];
    [self.myButton addTarget:self action:@selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];
    
    [self addSubview:self.myButton];
}

- (void)buttonTouched
{
    if ([self.delegate respondsToSelector:@selector(myButtonTouched)]) {

        [self.delegate myButtonTouched];
    }
}
@end


    這個例子封裝了一個View,這個View裏包含了一個按鈕,當點擊按鈕的時候,會給它的delegate對象發送一個myButtonTouched消息。 code

    從封裝的角度來看,這個例子沒有輸入,只有一個delegate輸出。咱們修改需求,如今咱們須要可以定製按鈕的title。orm

    有一種作法是把myButton這個屬性設置爲public屬性,而後外部程序直接修改它的title。對象

    還有一種作法是不開放myButton,而是設置一個工廠方法,在工廠方法裏去定製myButton的title。接口

咱們來分析一下這兩種方法的通用性和安全性:get

安全性:   it

     採用第一種方法,當有多個外部類都引用了同一個例子對象,其中某個外部類將self.myButton設置爲nil,很明顯,其餘外部類會出錯。

     第二種方法則不會。

通用性:

    採用第一種方法,當有多個外部類使用了例子類,當例子類進行版本升級,修改了按鈕的變量名,其餘外部類會出錯,必須逐個找出調用的具體代碼行進行修改。

    第二種方法不須要這樣。

   上面的例子告訴咱們封裝的第一個原則:

   不要讓任何外部類可以看到封裝類的內部變量或內部方法。

   若是將某個內部方法開放出來做爲對外的接口,則必須在任意版本中保持方法的輸入,輸出及方法名稱不變。

剛纔例子的變化版本:

#import <UIKit/UIKit.h>

@protocol MyControlViewDelegate <NSObject>

@optional
- (void)myButtonTouched;

@end

@interface MyControlView : UIView

@property (nonatomic, weak) id<MyControlViewDelegate> delegate;

- (id)initWithFrame:(CGRect)frame ButtonTitle:(NSString *)buttonTitle;

@end


#import "MyControlView.h"

@interface MyControlView()

@property (nonatomic, strong) NSString *buttonTitle;
@property (nonatomic, strong) UIButton *myButton;

@end

@implementation MyControlView

- (id)initWithFrame:(CGRect)frame ButtonTitle:(NSString *)buttonTitle
{
    self = [super initWithFrame:frame];
    if (self) {
        
        self.buttonTitle = buttonTitle;
        [self setupInterface];
    }
    
    return self;
}

- (void)setupInterface
{
    self.myButton = [UIButton buttonWithType:UIButtonTypeCustom];
    self.myButton.frame = CGRectMake(50, 50, 200, 50);
    [self.myButton setTitle:self.buttonTitle forState:UIControlStateNormal];
    [self.myButton addTarget:self action:@selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];

    [self addSubview:self.myButton];
}

- (void)buttonTouched
{
    if ([self.delegate respondsToSelector:@selector(myButtonTouched)]) {
        
        [self.delegate myButtonTouched];
    }
}

@end
相關文章
相關標籤/搜索