fb_license

技術標籤

@selector (1) 初使化區塊 (1) 物件 (1) 物件導向 (2) 型別 (4) 封裝 (1) 流程控制 (1) 陣列 (3) 推論型別 (2) 實機測試 (1) 蓋索林(gasolin) (1) 模組 (1) 憑證 (1) 轉型 (1) 羅康鴻 (121) 類別 (1) 變數 (5) Accelerometer (1) ActiveRecord (1) Activity (1) AFNetworking (1) alloc (1) Android (3) Animation (1) App (1) App ID (1) APP上傳 (1) ASP.NET (1) AVAudioPlayer (1) block (1) C# (2) class (1) CLLocationManager (1) CLLocationManagerDelegate (1) CMMotionManager (4) Controller (1) delegate (1) DELETE語法 (1) Device Motion資料 (1) Dialog (1) DropDownList (1) dynamic language (2) Facebook SDK (9) FBRequest (5) FBRequestConnection (2) FMDB (1) Gesture Recognizers (6) GROUP BY (2) Gyro (1) HAVING (1) IBAction (1) IBOutlet (1) id (3) inheritance (1) init (1) Insert (1) instance variable (1) Interface Builder (1) iOS (70) iOS idea (7) iOS Introduction (1) Layout (1) Magnetometer (1) Menu (2) Method (2) MKMapView (1) MKPointAnnotation (1) MS SQL (5) Nil (1) NSArray (1) NSDictionary (1) NSError (1) NSFileManager & .plist (1) NSMutableArray (1) NSMutableDictionary (1) NSNotificationCenter (1) NULL (1) object (2) Objective-C (16) Objective-C idea (1) ORDER BY (1) Parameter (1) property (1) protocol (2) Provisioning (1) Proximate Sensor (1) Q and A (2) R類別 (1) Rails (9) RESTful SOA (9) Ruby (8) Scene (1) SEELECT (1) Segue (2) SEL (1) SELECT語法 (1) Shake (1) Simulator (1) SOA (8) SQL (6) SQL Server (5) SQL函數 (1) SQL彙總函數 SQL (1) SQLite (1) Storyboard (1) Style (1) Swift (1) Table (1) target & action (1) Theme (1) Toast (1) TRUNCATE TABLE語法 (1) UIActionSheet (1) UIActionSheetDelegate (1) UIActivityIndicatorView (1) UIAlertView (1) UIBarButtonItem (1) UIButton (1) UICollectionView (1) UICollectionViewDataSource (1) UIControl (9) UIDatePicker (1) UIImage (1) UIImagePickerController (2) UIImagePickerControllerDelegate (2) UIImageView (1) UILabel (1) UILongPressGestureRecognizer (1) UINavigationController (2) UIPanGestureRecognizer (1) UIPinchGestureRecognizer (1) UIProgressView (1) UIResponder (1) UIRotationGestureRecognizer (1) UISegmentedControl (1) UISlider (1) UIStepper (1) UISwipeGestureRecognizer (1) UISwitch (1) UITabBarController (1) UITableView (1) UITableViewDataSource (1) UITapGestureRecognizer (1) UITextField (1) UITextFieldDelegate (1) UITextView (2) UITextViewDelegate (1) UIToolBar (1) UIView (8) UIWebView (1) UPDATE語法 (1) var (2) VB.NET (7) View (4) WHERE子句 (1) XML (1)

2014/02/25

[Objective-C] 我有一個叫別人做事的訊息 - SEL, @selector & performSelector


idea...



我知道我想要叫某個裝置播放影片,有可能是iPad也有可能是iPhone,看哪台拿到我手上我就放影片,這要如何作到呢?
我是SEL,
我可以將你要播放影片的訊息保留起來,
你只需要透過@selector描述你的訊息,
如此就可以取得我這個保留訊息的SEL。

我是物件object,
之後您只要透過我的performSelector,
我就可以幫你執行看看您保留在SEL中的訊息所要作的事了,
當然,如果我是iPad或iPhone,
我一定就能幫您處理播放影片的訊息。




1. 建立iPad與iPhone類別
  • 新增Objective-C class檔案,取名為iPad
  • 再新增Objective-C class檔案,取名為iPhone
2. 宣告播放影片方法
  • 在iPad.h與iPhone.h檔中,宣告簡單的播放影片方法-(void)playVideo
iPad.h #import <Foundation/Foundation.h> @interface iPad : NSObject -(void) playVideo; @end iPhone.h #import <Foundation/Foundation.h> @interface iPhone : NSObject -(void) playVideo; @end

3. 實作播放影片方法
  • 同樣的,在iPad.m與iPhone.m檔中,於-(void)playVideo方法後加上大括號以實作方法

iPad.m #import "iPad.h" @implementation iPad -(void) playVideo { NSLog(@"iPad放影片"); } @end iPhone.m #import <Foundation/Foundation.h> #import "iPhone.h" @implementation iPhone -(void) playVideo { NSLog(@"iPhone播放影片"); } @end

4. @selector產生叫別人作事的訊息
  • 透過@selector取得播放影片的訊息物件SEL
import <Foundation/Foundation.h> #import "iPad.h" #import "iPhone.h" int main(int argc, const char * argv[]) { @autoreleasepool { //透過@selector取得訊息物件SEL,而訊息物件裡所要傳送的訊息就是playVideo SEL playVideoSEL = @selector(playVideo); } return 0; }

5. performSelector執行訊息
  • 透過傳送performSelector訊息至iPad或iPhone中,以執行存放在SEL訊息物件中的播放影片訊息,如此就執到透過SEL訊息物件的方式,隨時叫別人接收做某件事的訊息了
import <Foundation/Foundation.h> #import "iPad.h" #import "iPhone.h" int main(int argc, const char * argv[]) { @autoreleasepool { //透過@selector取得訊息物件SEL,而訊息物件裡所要傳送的訊息就是playVideo SEL playVideoSEL = @selector(playVideo); //透過performSelector執行SEL中的playVideo訊息, //以達到iPad播放影片的目的 iPad * pad1 = [[iPad alloc] init]; [pad1 performSelector:playVideoSEL]; //透過performSelector執行SEL中的playVideo訊息, //以達到iPhone播放影片的目的 //在此您可發現,同樣的一件事一個訊息被保存在SEL物件中, //而後即可隨意的傳遞給任何物件去做這個訊息, //如此就做到有一個特定的事(訊息), //但可隨時叫別入做的需求 iPhone * phone1 = [[iPhone alloc] init]; [phone1 performSelector:playVideoSEL]; } return 0; }

檔案連結:objective_c_method_selector.zip


performSelector與回傳值:
performSelector也可在執行SEL訊息物件中的訊息後回傳值,而回傳的資料型別會以通用型別id來表示,後續會提供id型別的使用方式。

執行帶有參數的SEL:
透過performSelector帶有withObject參數的方法,即可傳遞物件型的參數。特別注意的是performSelector最多支援2個物件型的參數,如下範例:

#import <Foundation/Foundation.h> #import "iPad.h" #import "iPhone.h" int main(int argc, const char * argv[]) { @autoreleasepool { SEL playVideoSEL = @selector(playVideoWithVolume:inFullScreen:); iPad * pad1 = [[iPad alloc] init]; [pad1 performSelector:playVideoSEL withObject:[NSNumber numberWithInteger: 5] withObject:[NSNumber numberWithInteger: 1]]; iPhone * phone1 = [[iPhone alloc] init]; [phone1 performSelector:playVideoSEL withObject:[NSNumber numberWithInteger: 5] withObject:[NSNumber numberWithInteger: 1]]; } return 0; }


執行時,傳遞無法執行的訊息時會發生錯誤:
若傳遞一個不存在的訊息,則會在執行時發生錯誤,告訴您找不到對應的方法,無法執行,這是動態語言的特別,動態的去找是否有對應的方法可執行,若找不到則會產生錯誤。