Objective-C中一種消息處理方法performSelector: withObject:

2020-12-11 開源中國

華為雲虛擬機化創新丨數據中心大二層網絡技術揭秘!>>>

Objective-C中調用函數的方法是「消息傳遞」,這個和普通的函數調用的區別是,你可以隨時對一個對象傳遞任何消息,而不需要在編譯的時候聲明這些方法。所以Objective-C可以在runtime的時候傳遞人和消息。

 

首先介紹兩個方法 SEL和@selector

根據AppleObjective-C Runtime Reference官方文檔這個傳遞消息的函數就是 id objc_msgSend(id theReceiver, SEL theSelector, …)

theReceiver是接受消息的對象類型是id,theSelector是消息名稱類型是SEL。下邊代碼我們來看看如何來生成一個SEL,如果傳遞消息。

首先建立一個簡單的函數

- (void) fooNoInputs {

NSLog(@"Does nothing");

}

然後調用它

[self performSelector:@selector(fooNoInputs)];

第二個試驗看看如何在消息中傳遞參數

我們建立一個有input參數的函數

- (void) fooOneIput:(NSString*) first {

NSLog(@"Logs %@", first);

}

然後調用它

[self performSelector:@selector(fooOneInput:) withObject:@"first"];

第三個試驗更多的參數

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {

NSLog(@"Logs %@ then %@", first, second);

}

然後調用它

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];

第四個試驗如何建立動態的函數,然後調用他們?我們需要建立一個selector

SEL myTestSelector = @selector(myTest:);

並且我們調用的函數在另外一個Class內

- (void)abcWithAAA: (NSNumber *)number {

int primaryKey = [number intValue];

NSLog("%i", primaryKey);

}

MethodForSelectors * mfs = [[MethodForSelectors alloc]init];

NSArray *Arrays = [NSArray arrayWithObjects:@"AAA", @"BBB", nil];

for ( NSString *array in Arrays ){

SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);

mfs = [[MethodForSelectors alloc] performSelector:customSelector withObject:0];

}

注意:updated at 20120606

1.如果使用了ARC會產生「performSelector may cause a leak because its selector is unknown」警告
2.這種方式當傳入一個不符合約定的消息時會繼續運行並不報錯。例如應該傳入2個參數,但只傳入1個參數。或傳入了3個參數,第三個參數不會被初始化。

還有一種調用其他Class Function的方法是,但是不能有參數,我們這裡假設沒有參數,那麼就可以這樣

[mfs customSelector]; 

完整的代碼:

@implementation ClassForSelectors
- (void) fooNoInputs {

NSLog(@"Does nothing");

}

- (void) fooOneIput:(NSString*) first {

NSLog(@"Logs %@", first);

}

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {

NSLog(@"Logs %@ then %@", first, second);

}

 

- (NSArray *)abcWithAAA: (NSNumber *)number {

int primaryKey = [number intValue];

NSLog("%i", primaryKey);

}

 

- (void) performMethodsViaSelectors {

[self performSelector:@selector(fooNoInputs)];

[self performSelector:@selector(fooOneInput:) withObject:@"first"];

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];

}

 

- (void) performDynamicMethodsViaSelectors {

MethodForSelectors * mfs = [MethodForSelectors alloc];

NSArray *Arrays = [NSArray arrayWithObjects:@"AAA"@"BBB"nil];

forNSString *array in Arrays ){

SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);

mfs = [[MethodForSelectors allocperformSelector:customSelector withObject:0];

}

}

@end

 

@implementation MethodForSelectors

- (void)abcWithAAA: (NSNumber *)number {

NSLog("%i", number);

}

@end

 

 

--EOF--

原文連結:

http://www.cnblogs.com/buro79xxd/archive/2012/04/10/2440074.html

相關焦點

  • 深入理解Objective-C的Runtime機制
    Runtime數據結構在Objective-C中,使用[receiver message]語法並不會馬上執行receiver對象的message方法的代碼,而是向receiver發送一條message消息,這條消息可能由receiver來處理,也可能由轉發給其他對象來處理,也有可能假裝沒有接收到這條消息而沒有處理。
  • Objective-C 與 Runtime:為什麼是這樣?
    ,metaclass的首個成員自然也是isa的Class類型的指針變量,不同的是元類的isa最終指向的是它自身,由此我們可以觀察到,類struct是一種遞歸嵌套的設計,它正體現了面向對象無限抽象的理念,最終實現上指向自己則是實際工程處理的需要。
  • 深入理解Object-C消息轉發機制
    若想令類能理解某條消息,我們必須以程序碼實現出對應的方法才行。但是,在編譯器向類發送了其無法解讀的消息並不會報錯,因為在運行期可以繼續向類中添加方法(動態添加),所以編譯器在編譯時還無法確知類中到底會不會有某個方法實現。當對象接收到無法解讀的消息後,就會啟動「消息轉發」(message forwarding)機制,程式設計師可經由此過程告訴對象應該如何處理未知消息。
  • 輕鬆學習之 Objective-C消息轉發 乾貨
    首先,你需要知道這兩個概念:OC中調用方法就是向對象發送消息。比如 :[person run];這實際上這是在給person這個對象發送run這個消息。那麼問題來了,當run這個方法只有定義沒有實現會怎麼樣呢?
  • ES6對象新增方法-Object.is與Object.assign
    參考文獻:《ES6 標準入門》    ES6中最讓人享福的地方之一就是它的新增數組應用的方法,同時,數組是JavaScript中最常見的數據集合
  • 聊聊 Objective-C 循環引用的檢測
    這時候就需要有一種檢測方案,可以實時檢測對象之間是否發生了循環引用,來輔助開發者及時地修正代碼中存在的內存洩漏問題。要想檢測出循環引用,最直觀的方式是遞歸地獲取對象強引用的其他對象,並判斷檢測對象是否被其路徑上的對象強引用了,也就是在有向圖中去找環。明確檢測方式之後,接下來需要解決的是如何獲取強引用鏈,也就是獲取對象的強引用,尤其是最容易造成循環引用的 block。
  • Objective-C的元組實現(JDTuple)
    元組(tuple)是一種數據結構,它本來是一種關係型資料庫的概念,用來描述一張表中的一條數據。例如:那麼一行數據就是一個元組,即: tuple1 = (阿強,18,戰士);tuple2 = (阿珍,28,法師)。這個概念後來也被使用在代碼中,成為一種數據封裝的工具。元組可以包含任意個數和任意類型的數據,具體元組中包含什麼,取決於使用時的定義。
  • 10個Objective-C基礎面試題,iOS面試必備
    3、Object-C有私有方法嗎?私有變量呢?objective-c – 類裡面的方法只有兩種, 靜態方法和實例方法. 這似乎就不是完整的面向對象了,按照OO的原則就是一個對象只暴露有用的東西. 如果沒有了私有方法的話, 對於一些小範圍的代碼重用就不那麼順手了.
  • Objective-C 裡的 eval
    iOS 因為其封閉性,選手調試、主辦方運維都很困難,所以此前很少出現在 ctf 競賽中。DEFCON CTF 27 決賽有一個 TelOoOgram,是運行在 iOS 虛擬機 Corellium 上的,應該是史上第一次在 attack & defense 環節出現 iOS。
  • Swift和Objective-C混編
    會做下面的處理:已經用nonnull、nullable和 null_resettable修飾的屬性,按照Nullability and Optionals說的,轉成可選和非可選屬性。雖然調用形式一樣,方法在Swift中還是會轉換為方法,只有Objective-C中用@property聲明的變量才能轉為Swift中的屬性。關於方法的引入和調用可以參考方法的使用。方法的使用在Swift中,用點語法來調用Objective-C方法。
  • Objective-C 和 Swift 面試題
    這是內存洩漏的一種情況。Objective-C中若要調用Swift代碼,可以導入Swift生成的頭函數ProjectName-Swift.h來實現。Swift文件中若要規定固定的方法或屬性暴露給Objective-C使用,可以在方法或屬性前加上@objc來聲明。如果該類是NSObject子類,那麼Swift會在非private的方法或屬性前自動加上@objc。
  • Object.assign 原理及其實現
    = Object.assign(a, b);console.log(c);console.log(a === c);b.name = "change";b.book.price = "55";console.log(b);console.log(a);1、在第一步中,使用 Object.assign
  • 聊聊 CSS3 中的 object-fit 和 object-position
    趁著今天有點空閒,決定再來折騰一下CSS3中的兩個屬性:object-fit和object-position。這兩個奇葩的屬性是做什麼的呢?其實它們是為了處理替換元素(replaced elements)的自適應問題,簡單的說,就是處理替換元素的變形(這裡指長寬比例變形)問題。
  • Swift學習: 從Objective-C到Swift
    也就是我們聲明的方式簡化為簡單的一種,簡單來說在Swift中,我們只與property打交道。for index in stride(from: 1, through: 5, by: 2) { print(index)}然後對字典的遍歷也增強了.在Objective-c的快速枚舉中我們只能對字典的鍵進行枚舉。
  • iOS 消息轉發
    (3)如果尋找備援接收者的過程中返回值為nil的話,那麼會進入到完整的消息轉發流程中。 完整的消息轉發流程:首先創建NSInvocation對象,把與尚未處理的那條消息有關的全部細節都封於其中,此對象包含選擇子、目標(target)及參數。在出發NSInvocation對象時,「消息派發系統」(message-dispatch system)將親自出馬,把消息指派給目標對象。
  • Objective-C :方法
    在《2020的Objective-C》中大概描述了方法的種類與方法是如何進行調用的,這篇筆記詳細進行下總結。
  • 詳細談談Pandas中replace方法的使用
    Pandas中有一個replace方法,不論是Series還是DataFrame中,都可以使用。但是,有一點值得大家學習,掌握,就是到底用不用加.str呢?以及對於多個字符的替換該如何操作呢?= True)>>> s10 a1 B2 cdtype: object>>> s2.replace(2,22,inplace = True)>>> s20 11 222 3dtype: int64很多時候,不論是書中,還是官方文檔中,都會出現Series後加.str.replace方法,簡言之
  • 不想用Object和Array存儲數據,你還有Set和Map
    除了這兩個選項外,沒有其他選擇來存儲多個值和處理數據結構。然而,在使用Object和Array時有幾個限制,例如:· Array可以存儲重複的元素。· 沒有像Array那樣找到Object長度的方法。· 只有字符串可以存儲在Object中,不記插入順序。
  • 在 Flutter 中玩轉 Objective-C Block
    Dart 語言中的 Function 可以當做閉包,可以實現下面這樣的效果:stub.fooBlock((NSObject a) { print('hello block!,步驟如下:• 用 libffi 動態創建相同籤名的函數,• 準備好創建 Block 需要的 flag、description、signature 和 wrapper 對象等• 根據 Block 的內存模型創建對應的結構體(棧上)• 把 Block 對象 copy 到堆上,並發送 autorelease 消息這上面每一步其實都不簡單
  • Day4.利用Pandas做數據處理
    Series對象Series是Pandas中最基本的對象,代表著一維的序列,類似一種一維數組。和 NumPy的一維的數組不同,Series 能為數據自定義標籤,也就是索引(index),然後通過索引來訪問數組中的數據。