performSelector 官方文檔
向接收方發(fā)送指定的消息并返回消息的結(jié)果
- (id)performSelector:(SEL)aSelector;
// aSelector
標(biāo)識要發(fā)送的消息的選擇器。消息不應(yīng)該接受任何參數(shù)。
如果aSelector為空,則會引發(fā)一個NSInvalidArgumentException
// Return Value
消息的結(jié)果的對象
// 描述
方法等效于直接向接收方發(fā)送aSelector消息。
例如,下面的消息都做同樣的事情:
id aClone = [anObject copy];
id aClone = [anObject performSelector:@selector(copy)];
id aClone = [anObject performSelector:sel_getUid("copy")];
方法允許您發(fā)送直到運行時才確定的消息。
這意味著你可以傳遞一個變量選擇器作為參數(shù):
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
id returnedObject = [anObject performSelector:aSelector];
但是在這樣做的時候要小心。
對于返回的對象,不同的消息需要不同的內(nèi)存管理策略,使用哪種策略可能并不明顯。
通常調(diào)用者不負(fù)責(zé)返回對象的內(nèi)存,但如果選擇器是創(chuàng)建方法之一(比如copy),就不是這樣了。
有關(guān)所有權(quán)期望的描述,請參閱高級內(nèi)存管理編程指南中的內(nèi)存管理策略。
根據(jù)代碼的結(jié)構(gòu),可能不清楚在任何給定調(diào)用中使用哪種選擇器。
由于這種不確定性,如果在使用ARC管理內(nèi)存時提供變量選擇器,編譯器將生成一個警告。
因為ARC不能在編譯時確定返回對象的所有權(quán),所以它假設(shè)調(diào)用者不需要獲得所有權(quán),但這可能不是真的。
編譯器警告警告您潛在的內(nèi)存泄漏。
為了避免警告,如果您知道aSelector沒有返回值,您可以使用performSelectorOnMainThread:withObject:waitUntilDone:或NSObject中可用的相關(guān)方法之一 。
對于更通用的解決方案,使用NSInvocation構(gòu)造一個消息,您可以使用任意參數(shù)列表和返回值來調(diào)用該消息。
或者,考慮重新構(gòu)造代碼,使用塊作為通過API傳遞功能塊的一種方法。有關(guān)詳細(xì)信息,請參見塊編程主題。
performSelector 用法
// 沒有返回值
[self performSelector:@selector(test1)];
// 有返回值
id returnValue = [self performSelector:@selector(test2)];
NSLog(@"%@",returnValue);
// 有一個參數(shù)
[self performSelector:@selector(test3:) withObject:@"345"];
- (void)test1
{
NSLog(@"1");
}
- (NSString *)test2
{
return @"23";
}
- (void)test3:(NSString *)param
{
if (param == nil)
param = @"empty";
NSLog(@"%@",param);
}
// 打印結(jié)果 1 、 23 、345
performSelector:withObject: 官方文檔
以對象作為參數(shù)向接收者發(fā)送消息。
- (id)performSelector:(SEL)aSelector withObject:(id)object;
// 參數(shù) object
作為消息唯一參數(shù)的對象
// 描述
這個方法與performSelector相同:只是您可以為aSelector提供一個參數(shù)。
aSelector應(yīng)該識別一個只接受id類型參數(shù)的方法。
對于具有其他參數(shù)類型和返回值的方法,使用NSInvocation。
performSelector:withObject:withObject:官方文檔
用兩個對象作為參數(shù)向接收者發(fā)送消息。
其他和傳遞一個參數(shù)時一樣
performSelector:withObject:afterDelay:官方文檔
在延遲之后,使用默認(rèn)模式在當(dāng)前線程上調(diào)用接收方的方法。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
該方法不應(yīng)該有顯著的返回值,應(yīng)該只接受id類型的一個參數(shù),或者不接受參數(shù)。
// anArgument
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// delay
發(fā)送消息之前的最小時間。
指定延遲為0并不一定會立即執(zhí)行選擇器。
選擇器仍然在線程的運行循環(huán)中排隊并盡快執(zhí)行。
// 描述
此方法設(shè)置一個計時器,以在當(dāng)前線程的運行循環(huán)上執(zhí)行aSelector消息。
計時器被配置為以默認(rèn)模式(NSDefaultRunLoopMode)運行。
當(dāng)計時器觸發(fā)時,線程嘗試從運行循環(huán)中取出消息并執(zhí)行選擇器。
如果運行循環(huán)正在運行且處于默認(rèn)模式,則成功;否則,計時器將等待運行循環(huán)處于默認(rèn)模式。
如果您希望在運行循環(huán)處于默認(rèn)模式之外的模式時刪除消息,請使用performSelector:withObject:afterDelay:inModes:方法。
如果不確定當(dāng)前線程是否是主線程,可以使用performSelectorOnMainThread:withObject:waitUntilDone:或performSelectorOnMainThread:withObject:waitUntilDone:modes: method來確保選擇器在主線程上執(zhí)行。
要取消隊列消息,使用cancelPreviousPerformRequestsWithTarget:或cancelPreviousPerformRequestsWithTarget:selector:object: method。
// 特殊注意事項
此方法注冊其當(dāng)前上下文的runloop,并依賴于定期運行該runloop來正確執(zhí)行。
在一個公共上下文中,當(dāng)分派隊列調(diào)用此方法時,您可能會調(diào)用此方法,并最終注冊一個不定期自動運行的runloop。
如果在調(diào)度隊列上運行時需要這種類型的功能,則應(yīng)該使用dispatch_after和相關(guān)方法來獲得所需的行為。
performSelectorOnMainThread:withObject:waitUntilDone:官方文檔
使用默認(rèn)模式在主線程上調(diào)用接收器的方法。
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
該方法不應(yīng)該有顯著的返回值,應(yīng)該只接受id類型的一個參數(shù),或者不接受參數(shù)。
// arg
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// wait
一個布爾值,指定當(dāng)前線程是否阻塞,直到在主線程的接收器上執(zhí)行指定的選擇器之后。
指定YES來阻塞此線程;否則,請指定NO以便立即返回此方法。
如果當(dāng)前線程也是主線程,并且您為該參數(shù)指定YES,則消息將立即被傳遞和處理。
// 描述
您可以使用此方法將消息傳遞到應(yīng)用程序的主線程。
主線程包含應(yīng)用程序的主運行循環(huán),并且是NSApplication對象接收事件的地方。
本例中的消息是要在線程上執(zhí)行的當(dāng)前對象的方法。
該方法使用公共運行循環(huán)模式(即與NSRunLoopCommonModes常量關(guān)聯(lián)的模式)在主線程的運行循環(huán)上對消息進(jìn)行排隊。
作為其正常運行循環(huán)處理的一部分,主線程刪除消息隊列(假設(shè)它正在以一種常見的運行循環(huán)模式運行),并調(diào)用所需的方法。
來自同一線程對該方法的多個調(diào)用會導(dǎo)致相應(yīng)的選擇器排隊,并按照調(diào)用的相同順序執(zhí)行。
不能使用此方法取消排隊的消息。
如果希望取消當(dāng)前線程上的消息,必須使用performSelector:withObject:afterDelay:或performSelector:withObject:afterDelay:inModes:方法。
// 特殊注意事項
此方法注冊其當(dāng)前上下文的runloop,并依賴于定期運行該runloop來正確執(zhí)行。
在一個公共上下文中,當(dāng)分派隊列調(diào)用此方法時,您可能會調(diào)用此方法,并最終注冊一個不定期自動運行的runloop。
如果在調(diào)度隊列上運行時需要這種類型的功能,則應(yīng)該使用dispatch_after和相關(guān)方法來獲得所需的行為。
performSelectorInBackground:withObject:官方文檔
在新的后臺線程上調(diào)用接收方的方法。
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
此方法在應(yīng)用程序中創(chuàng)建一個新線程,如果應(yīng)用程序尚未處于多線程模式,則將其置于多線程模式。
由aSelector表示的方法必須像設(shè)置程序中的任何其他新線程一樣設(shè)置線程環(huán)境。
有關(guān)如何配置和運行線程的更多信息,請參閱線程編程指南。
performSelector:target:argument:order:modes:官方文檔
在接收端調(diào)度消息的發(fā)送。
- (void)performSelector:(SEL)aSelector target:(id)target argument:(id)arg order:(NSUInteger)order modes:(NSArray<NSRunLoopMode> *)modes;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
這個方法不應(yīng)該有一個重要的返回值,應(yīng)該只接受一個id類型的參數(shù)。
// target
在aSelector中定義選擇器的對象
// arg
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// order
消息的優(yōu)先級。
如果計劃了多個消息,則在發(fā)送順序值較高的消息之前發(fā)送順序值較低的消息。
// modes
用于發(fā)送消息的輸入模式數(shù)組。
您可以指定自定義模式或使用運行循環(huán)模式中列出的模式之一。
// 描述
此方法設(shè)置一個計時器,以便在下一個運行循環(huán)迭代開始時在接收器上執(zhí)行aSelector消息。
計時器被配置為以模式參數(shù)指定的模式運行。
當(dāng)計時器觸發(fā)時,線程嘗試從運行循環(huán)中取出消息并執(zhí)行選擇器。
如果運行循環(huán)正在運行且處于指定模式之一,則成功;否則,計時器將等待運行循環(huán)處于其中一種模式。
此方法在發(fā)送aSelector消息之前返回。
接收器保留目標(biāo)對象和參數(shù)對象,直到選擇器的計時器觸發(fā),然后作為清理的一部分釋放它們。
如果希望在處理完當(dāng)前事件之后發(fā)送多個消息,并且希望確保這些消息以特定的順序發(fā)送,請使用此方法。
performSelector:onThread:withObject:waitUntilDone:官方文檔
使用默認(rèn)模式在指定線程上調(diào)用接收方的方法。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
該方法不應(yīng)該有顯著的返回值,應(yīng)該只接受id類型的一個參數(shù),或者不接受參數(shù)。
// thr
執(zhí)行選擇器的線程。
// arg
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// wait
一個布爾值,指定當(dāng)前線程是否阻塞,直到在指定線程的接收器上執(zhí)行指定的選擇器之后。
指定YES來阻塞此線程;否則,請指定NO以便立即返回此方法。
如果當(dāng)前線程和目標(biāo)線程相同,并且為該參數(shù)指定YES,則立即在當(dāng)前線程上執(zhí)行選擇器。
如果指定NO,此方法將消息排隊到線程的run循環(huán)并返回,就像它對其他線程所做的一樣。
然后,當(dāng)前線程必須在有機(jī)會時退出隊列并處理消息。
// 描述
您可以使用此方法將消息傳遞到應(yīng)用程序中的其他線程。
本例中的消息是要在目標(biāo)線程上執(zhí)行的當(dāng)前對象的方法。
該方法使用默認(rèn)的運行循環(huán)模式(即與NSRunLoopCommonModes常量關(guān)聯(lián)的模式)在目標(biāo)線程的運行循環(huán)上對消息進(jìn)行排隊。
作為其正常運行循環(huán)處理的一部分,目標(biāo)線程刪除消息隊列(假設(shè)它正在以一種默認(rèn)的運行循環(huán)模式運行),并調(diào)用所需的方法。
不能使用此方法取消排隊的消息。
如果希望取消當(dāng)前線程上的消息,必須使用performSelector:withObject:afterDelay:或performSelector:withObject:afterDelay:inModes:方法。
// 特殊注意事項
此方法注冊其當(dāng)前上下文的runloop,并依賴于定期運行該runloop來正確執(zhí)行。
在一個公共上下文中,當(dāng)分派隊列調(diào)用此方法時,您可能會調(diào)用此方法,并最終注冊一個不定期自動運行的runloop。
如果在調(diào)度隊列上運行時需要這種類型的功能,則應(yīng)該使用dispatch_after和相關(guān)方法來獲得所需的行為。
performSelector:onThread:withObject:waitUntilDone:modes:官方文檔
使用指定模式在指定線程上調(diào)用接收器的方法。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
它不應(yīng)該有一個重要的返回值,應(yīng)該只接受一個id類型的參數(shù),或者沒有參數(shù)。
// thr
執(zhí)行選擇器的線程。這個線程表示目標(biāo)線程。
// arg
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// wait
一個布爾值,指定當(dāng)前線程是否阻塞,直到在指定線程的接收器上執(zhí)行指定的選擇器之后。
指定YES來阻塞此線程;否則,請指定NO以便立即返回此方法。
如果當(dāng)前線程和目標(biāo)線程相同,并且為該參數(shù)指定YES,則立即執(zhí)行選擇器。
如果指定NO,此方法將對消息進(jìn)行排隊并立即返回,而不管線程是相同的還是不同的。
// array
一個字符串?dāng)?shù)組,它標(biāo)識允許在其中執(zhí)行指定選擇器的模式。
這個數(shù)組必須至少包含一個字符串。
如果為該參數(shù)指定nil或空數(shù)組,則此方法返回時不執(zhí)行指定的選擇器。
有關(guān)運行循環(huán)模式的信息,請參閱線程編程指南中的運行循環(huán)。
// 討論
您可以使用此方法將消息傳遞到應(yīng)用程序中的其他線程。
本例中的消息是要在目標(biāo)線程上執(zhí)行的當(dāng)前對象的方法。
此方法使用數(shù)組參數(shù)中指定的運行循環(huán)模式在目標(biāo)線程的運行循環(huán)上對消息進(jìn)行排隊。
作為其正常運行循環(huán)處理的一部分,目標(biāo)線程刪除消息隊列(假設(shè)它正在以指定的模式之一運行),并調(diào)用所需的方法。
不能使用此方法取消排隊的消息。
如果希望取消當(dāng)前線程上的消息,則必須使用performSelector:withObject:afterDelay:或performSelector:withObject:afterDelay:inModes:方法。
// 特殊注意事項
此方法注冊其當(dāng)前上下文的runloop,并依賴于定期運行該runloop來正確執(zhí)行。
在一個公共上下文中,當(dāng)分派隊列調(diào)用此方法時,您可能會調(diào)用此方法,并最終注冊一個不定期自動運行的runloop。
如果在調(diào)度隊列上運行時需要這種類型的功能,則應(yīng)該使用dispatch_after和相關(guān)方法來獲得所需的行為。
performSelectorOnMainThread:withObject:waitUntilDone:modes:官方文檔
使用指定的模式在主線程上調(diào)用接收器的方法。
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;
// aSelector
標(biāo)識要調(diào)用的方法的選擇器。
該方法不應(yīng)該有顯著的返回值,應(yīng)該只接受id類型的一個參數(shù),或者不接受參數(shù)。
// arg
調(diào)用方法時傳遞給該方法的參數(shù)。
如果方法不接受參數(shù),則傳遞nil。
// wait
一個布爾值,指定當(dāng)前線程是否阻塞,直到在主線程的接收器上執(zhí)行指定的選擇器之后。
指定YES來阻塞此線程;否則,請指定NO以便立即返回此方法。
如果當(dāng)前線程也是主線程,并且傳遞YES,則立即執(zhí)行消息,否則執(zhí)行將排隊下一次通過運行循環(huán)運行。
// array
一個字符串?dāng)?shù)組,它標(biāo)識允許在其中執(zhí)行指定選擇器的模式。
這個數(shù)組必須至少包含一個字符串。
如果為該參數(shù)指定nil或空數(shù)組,則此方法返回時不執(zhí)行指定的選擇器。
有關(guān)運行循環(huán)模式的信息,請參閱線程編程指南中的運行循環(huán)。
// 討論
您可以使用此方法將消息傳遞到應(yīng)用程序的主線程。
主線程包含應(yīng)用程序的主運行循環(huán),并且是NSApplication對象接收事件的地方。本例中的消息是要在線程上執(zhí)行的當(dāng)前對象的方法。
此方法使用數(shù)組參數(shù)中指定的運行循環(huán)模式在主線程的運行循環(huán)上對消息進(jìn)行排隊。
作為其正常運行循環(huán)處理的一部分,主線程刪除消息隊列(假設(shè)它正在以指定的模式之一運行)并調(diào)用所需的方法。
假設(shè)每個選擇器的關(guān)聯(lián)運行循環(huán)模式相同,則同一線程對該方法的多個調(diào)用會導(dǎo)致相應(yīng)的選擇器排隊,并以與調(diào)用相同的順序執(zhí)行。
如果為每個選擇器指定不同的模式,則跳過任何關(guān)聯(lián)模式與當(dāng)前運行循環(huán)模式不匹配的選擇器,直到運行循環(huán)隨后以該模式執(zhí)行為止。
不能使用此方法取消排隊的消息。
如果希望取消當(dāng)前線程上的消息,必須使用performSelector:withObject:afterDelay:或performSelector:withObject:afterDelay:inModes:方法。
// 特殊注意事項
此方法注冊其當(dāng)前上下文的runloop,并依賴于定期運行該runloop來正確執(zhí)行。
在一個公共上下文中,當(dāng)分派隊列調(diào)用此方法時,您可能會調(diào)用此方法,并最終注冊一個不定期自動運行的runloop。
如果在調(diào)度隊列上運行時需要這種類型的功能,則應(yīng)該使用dispatch_after和相關(guān)方法來獲得所需的行為。
cancelPreviousPerformRequestsWithTarget:selector:object:官方文檔
取消執(zhí)行先前在performSelector:with object:afterDelay:中注冊的請求。
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument;
// aTarget
先前用performSelector:withObject:afterDelay: 實例方法注冊的請求的目標(biāo)
// aSelector
先前用performSelector:withObject:afterDelay: 實例方法注冊的請求的選擇器。
// anArgument
先前用performSelector:withObject:afterDelay: instance方法注冊的請求的參數(shù)。
參數(shù)相等是使用isEqual:來確定的,因此值不必與最初傳遞的對象相同。
傳遞nil以匹配最初作為參數(shù)傳遞的nil請求。
// 討論
所有執(zhí)行請求都被取消,這些請求的目標(biāo)與aTarget相同,參數(shù)與參數(shù)相同,選擇器與選擇器相同。
此方法僅刪除當(dāng)前運行循環(huán)中的執(zhí)行請求,而不是所有運行循環(huán)。