ios代理
【iOS開發技術分享】協議與代理
【iOS開發技術分享】協議與代理
一、理解協議與代理
協議:
協議是一個方法簽名的列表,在其中可以定義若干個方法。根據配置,遵守該協議的類會去實現這個協議中規定的若干個方法。
代理:
代理是一個概念,很難用一個名詞去定義(如我們可以說協議其實就是一個方法列表)。它更像是一種關系,我要做某一個事情,但我自己不想去做這件事,我委託其他人幫我去做這件事。這個時候,這位其他人就是我的代理。
二、協議的使用
在定義協議時,可以通過@required與@optional來配置遵守這個協議必須去實現的方法和可以選擇的方法。譬如:
@protocol MyChooseDayViewDelegate<NSObject>
@required
- returnChooseDay:(id)myChooseDayView;
@optional
- hideThisView;
- changeDateFormatter:(NSString*)formatString;
@end
在定義的協議 MyChooseDayViewDelegate中,如果遵守該協議,就必須實現協議中的- returnChooseDay: 方法,同時可以根據實際程序要求去實現- hideThisView 與 - changeDateFormatter: 。
同時,協議支持對本身的一種擴展,譬如:
@protocol MyChooseTimeViewDelegate< MyChooseDayViewDelegate>
- doSomething;
@end
MyChooseTimeViewDelegate
擴展了MyChooseDayViewDelegate這個協議,也就是說,假如遵守了MyChooseTimeViewDelegate的話,也必須實
現MyChooseDayViewDelegate中的方法(@required)使用分類的話,就是在定義類的頭文件中使用<>
將所需要的協議引入,如果引入多個協議,用","分隔,譬如:
@interface MyClassView:UIViewController <MyChooseDayViewDelegate, UIAlertViewDelegate>
//TODO: balabalabala...
@end
想要檢查某個類是否實現了某個協議或者某個類是否實現了某個協議的方法,可以通過以下方式來進行測試
//獲取某個對象
MyClassView *myClassView = xxxxxxx;
//判斷該對象是否實現了MyChooseDayViewDelegate協議
if([myClassView conformToProtocol:@protocol (MyChooseDayViewDelegate)]){
//TODO: balabalabala...
}
//判斷對象是否實現了某個方法就用我們經常會使用到的
if([myClassView responseToSelector:@selector(xxxx)]){
//TODO: balabalabala...
}
三、代理
代理在iOS開發會被經常使用,而且代理的使用往往配合著協議。我重復一次我對他的理解,我要做某一個事情,但我自己不想去做這件事,我委託其他人幫我去做這件事。
舉例來說,我在辦公室里正在寫代碼,突然發現口
很渴像喝瓶冰百事,但下樓是件麻煩的事情,我不願意下樓。這個時候我想起小賣部可以商品加價2元就外送到家服務,我就打電話給小賣部,委託小賣部給我送一
瓶水上來。這個時候,小賣部就是我的代理,我委託他幫買水並送上來。這個例子中小賣部是我的代理,商品加價2元外送到家服務就是商品買賣協議(這個叫法肯
定不是最佳的,姑且這么叫吧)中的一個方法。
不要覺得麻煩,我們再最後理一遍,小賣部遵守商品買賣協議,我讓小賣部成為了我的代理,代替我完成了買瓶冰百事的事情。
以iOS開發的角度來說,UIViewController想使用一個tableview,需要遵守UITableviewDataSource,UITableViewDelegate這2個協議,同時設置tableview的代理為自身,才可以完整的實現Table。
四、代理與協議的使用
我盡可能的用代碼來進行描述,但首先需要進行一些context鋪墊
我想實現的功能:我要自定義一個View,這個
view可能展示了我自己項目中特定的一些信息,它可能是若干控制項的組合,譬如UITextField、UISwitch、UIDatePicker、
balabalabala...我們姑且叫這個view為myInformationView 我在一個ViewController使用了這個
view,為了方便,這個ViewController就叫myRootViewController。在使用這個myInformationView
時,我需要即時的在myRootViewController獲取並做相應的處理。這是我想實現的功能。
接下來,就是開始寫代碼的時刻:
1.首先是一個protocol
#import <Foundation/Foundation.h>
@class MyInformationView;
@protocol MyInformatioViewDelegate<NSObject>
@required
@returnValueToShow:(MyInformationView*)myInformationView;
@end
2.MyInformationView
#import <UIKit/UIKit.h>
@interface MyInformationView : UIView
@property (nonatomic, strong) id<MyInformationViewDelegate> myDelegate;
- (id)initWith......//初始化視圖的方法
//所需要的屬性和方法根據實際需要再行添加
@end
#import "MyInformationView.h"
@interface MyInformationView()
@end
@implementation MyInformationView
@synthesize myDelegate = _myDelegate;
//Todo: 處理一些初始化方法和其他一些事件
// changeMyInformationData 是操作此view可能產生的數據變動。它可能是選擇器變動、點擊按鈕等等,但我們並不想在此view處理它,因為它的變動可能對調用此view的controller造成影響,所以...
- (void) changeMyInformationData:(id)sender
{
//TODO:數據變動....
if ([self.myDelegate respondsToSelector:@selector(returnValueToShow:)]) {
[self.myDelegate returnValueToShow:self];
}
}
@end
3.ViewController
這里就不寫代碼了,在頭文件中聲明此類遵守MyInformationViewDelegate協議。在實現文件(.m)中,調用MyinfomationView的時候,設置代理成自己,
MyInformation *myInfoView = [[MyInformation alloc] init.......];
myInfoView.myDelegate = self;
然後實現協議中要求實現的方法
- (void)returnValueToShow:(MyInformationView*)myInfoView
{
//TODO:做想做的事情
}
② ios怎麼用代理獲取手機所有網路請求並分析
怎麼代理或手機的聯網的一些分析情況介紹給我查一下。
③ ios 怎麼設置數據代理
//設置代理 和方法 屬性
@protocol detailNoteProtocol <NSObject]]>
- (void)aa;
@end
//聲明代理屬性
@property (nonatomic, assign)id<detailNoteProtocol>delegate;
//制定接受代理方
if (_delegate && [_delegate respondsToSelector:@selector(aa)]) {
[_delegate aa];
}
接受代理
在.h 裡面
引入頭文件, 接受代理協議,
在.m 裡面
實現代理方法 , 記著寫 : _detailVC.delegate = self;
④ iOS中,代理是什麼
你是問開發中的代理么?還是網路的代理?
如果你是問開發中的代理的話,這是專設計模式,簡單點說,就屬是一個類實現不了或者不能實現的功能交給另一個能實現功能的類去做,就是代理。代理是一種常用的設計模式,如果做開發的話,建議你還是多看看這塊的東西。
如果你是問ios系統中網路的代理的話,那可以理解為VPN。瀏覽國外網站的時候需要設置代理。
⑤ iOS代理了協議之後沒法正常回調
關於代理不回調問題有以下幾問題:
1. 沒有設置代理 XXX.delegate = self
2. 方法名寫錯
3. 新方法得判斷iOS版本
4. 引用對象被釋放了
5. 具體功能info.plist配置錯誤
6. 在block中設置有時會出現代理不回調問題(用通知代替)
錯誤1,2 :
對於錯誤1,2一般是很新的新手或者老手腦袋短路極不正常時犯的錯誤。
錯誤3 :
這個錯誤一般也可以忽略,因為使用高級API程序直接會崩潰。 錯誤4
引用對象唄釋放了。
這個錯誤較之於上面三個有點難度,解決這個錯誤需要對內存管理有所了解.如果內存管理不好,這里也很容易出現EXC_BAD_ACCESS崩潰.所以檢查對象的生命周期,代理要設置成全局變數,不要設置成局部變數。
代理設置使用weak,避免造成循環引用.而且要在dealloc方法中將代理設置為nil。
* 注意: 不要使用assign,因為assgin類型在使用結束後不會設置成nil,此時發消息的話會EXC_BAD_ACCESS。
錯誤5
這個問題是在處理特定功能時才能遇到的,不具有普遍性.比如使用CLLocationManager獲取地理位置時不進代理的回調.你代理明明設置的很清楚,也遵循代理了,對象也沒有被釋放,但是代理就是不進,是不是很迷惑很糾結. 此時代理不進的另一個原因就是info.plist沒有配置正確。
因為獲取地理位置需要配置info.plist的屬性: 或者。
錯誤6
關於這個問題具體什麼需求可以以後討論一下,如果大家也遇到這個問題,這里可以作為一個小參考。
⑥ iOS 代理和通知的區別
------共同點
利用通知和代理都能完成對象間的通信。(比如A對象告訴D對象發生了什麼事情,A對象傳遞數據給D對象)
------不同點
代理:只能是一對一的關系(一個對象只能告訴另外一個對象發生了什麼事情)
通知:多對多關系(一個對象能告訴N個對象發生了什麼事情,一個對象能得知N個對象發生了什麼事情)
⑦ iOS代理和通知的區別
代理耦合度更高A、復B、C、D需要有生命周制期的耦合,代理用於比較明確的實例間的通知關系,比起通知可讀性會更好;
通知雖然耦合低但不能被濫用,適合單純廣播行為,因為可能B、C、D類不止一個實例,但期望的只是通知部分實例;通知還考慮多線程調用;
從模式上,一種是代理模式,一種算是觀察者模式。
⑧ 在ios 中,代理的方法怎麼實現
委託代理(degegate),顧名思義,把某個對象要做的事情委託給別的對象去做。那麼別的對象就是這個對象的代理,代替它來打理要做的事。反映到程序中,首先要明確一個對象的委託方是哪個對象,委託所做的內容是什麼。
A的頭文件:
[objc] view plain
#import <Foundation/Foundation.h>
@protocol <NSObject>
@optional
- (void)timeTickOut:(BOOL)backToSecret;
@end
@interface SecretGardenPicPopView : UIView
{
id<> _delegate;
}
@property (nonatomic, assign) id<> delegate;
@end
A的 .m 文件
[objc] view plain
#import "SecretGardenPicPopView.h"
#import "AppDelegate.h"
@implementation SecretGardenPicPopView
@synthesize delegate = _delegate;
- (void)dealloc
{
self.delegate = nil;
[super dealloc];
}
- (void)changeTimeTextLabel:(NSTimer *)timer
{
NSLog(@"===計數===>%d",_timeCount);
if (0 <= _timeCount) {
_timeLab.text = [NSString stringWithFormat:@"%d''", _timeCount];
} else {
[timer invalidate];
NSLog(@"代理===>%p",_delegate);
if (_delegate && [_delegate respondsToSelector:@selector(timeTickOut:)]) { //只有當代理存在,且timeTickOut方法被實現的時候才執行下面的語句
NSLog(@"執行代理");
[_delegate timeTickOut:NO];
}
}
_timeCount -= 1;
}
@end
B的頭文件:
[objc] view plain
#import "SecretGardenPicPopView.h" //A的頭文件
@interface SecretGardenController : BaseController<> //A的代理
@end
B的 .m文件:
[objc] view plain
- (void)timeTickOut:(BOOL)backToSecret
{
//Do Something
}
⑨ ios怎樣可以不連wifi使用http代理
1、首先,要有一個http代理。
2、關閉,就是直連,不經過代理;手動,就是把代理設置進去,填寫好http代理伺服器的地址、埠(如果有需要,寫帳號密碼進去),這樣所有的數據通信都會走http代理;自動,就是要配置pac文件,這樣經過配置後,根據設定的,有些數據走代理,有些數據走直連。
⑩ ios開發 頁面層級太多怎麼傳遞代理
一般而言層級關系太多都會選擇用通知,而不是代理,只要發出通知不管在哪裡都能夠監聽。
我做項目的時候也經常遇到這樣的情況,有一種情況是一個頁面有很多個不同類型的 cell, 每個cell中都有很多自定義子控制項,控制器需要監聽這些子控制項的相關出發事件,這種情況我選擇了代理沒有選擇通知 ,因為是不同類型的cell ,我使用的是cell工廠模式,都是批量操作,代理批量操作比較方便。
如果你不屬於我這樣的批量操作,建議用通知。