이 NSObject
메서드를 performSelector:withObject:afterDelay:
사용하면 일정 시간 후에 개체 인수를 사용하여 개체에 대한 메서드를 호출 할 수 있습니다. 객체가 아닌 인수 (예 : 정수, 부동 소수점, 구조체, 객체가 아닌 포인터 등)가있는 메서드에는 사용할 수 없습니다.
객체가 아닌 인수가있는 메서드로 동일한 작업을 수행 하는 가장 간단한 방법 은 무엇입니까 ? 나는 regular performSelector:withObject:
의 경우 해결책이 사용하는 것임을 알고 있습니다 NSInvocation
(그런데 정말 복잡합니다). 하지만 “지연”부분을 처리하는 방법을 모르겠습니다.
감사,
답변
다음은 NSInvocation을 사용하여 변경할 수없는 것을 호출하는 데 사용 된 것입니다.
SEL theSelector = NSSelectorFromString(@"setOrientation:animated:");
NSInvocation *anInvocation = [NSInvocation
invocationWithMethodSignature:
[MPMoviePlayerController instanceMethodSignatureForSelector:theSelector]];
[anInvocation setSelector:theSelector];
[anInvocation setTarget:theMovie];
UIInterfaceOrientation val = UIInterfaceOrientationPortrait;
BOOL anim = NO;
[anInvocation setArgument:&val atIndex:2];
[anInvocation setArgument:&anim atIndex:3];
[anInvocation performSelector:@selector(invoke) withObject:nil afterDelay:1];
답변
float, boolean, int 또는 이와 유사한 것을 NSNumber로 감싸십시오.
구조체의 경우 편리한 솔루션을 모르지만 이러한 구조체를 소유하는 별도의 ObjC 클래스를 만들 수 있습니다.
답변
이 답변을 사용하지 마십시오. 나는 역사적 목적으로 만 남겨 두었습니다. 아래 설명을 참조하십시오.
BOOL 매개 변수 인 경우 간단한 트릭이 있습니다.
아니요에는 nil을 전달하고 YES에는 self를 전달하십시오. nil은 BOOL 값 NO로 캐스트됩니다. self는 YES의 BOOL 값으로 캐스트됩니다.
이 접근 방식은 BOOL 매개 변수가 아닌 경우 분류됩니다.
self가 UIView라고 가정합니다.
//nil will be cast to NO when the selector is performed
[self performSelector:@selector(setHidden:) withObject:nil afterDelay:5.0];
//self will be cast to YES when the selector is performed
[self performSelector:@selector(setHidden:) withObject:self afterDelay:10.0];
답변
아마도 NSValue , 지연 후에도 포인터가 여전히 유효한지 확인하십시오 (즉, 스택에 할당 된 객체가 없음).
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 iOS SDK 4 이상을 빌드하는 경우 블록을 사용하여 아주 적은 노력으로이 작업을 수행하고 더 읽기 쉽게 만들 수 있습니다.
double delayInSeconds = 2.0;
int primitiveValue = 500;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self doSomethingWithPrimitive:primitiveValue];
});
답변
PerformSelector : WithObject는 항상 객체를 취하므로 int / double / float 등과 같은 인수를 전달하기 위해 ….. 이와 같은 것을 사용할 수 있습니다.
//NSNumber is an object..
[self performSelector:@selector(setUserAlphaNumber:) withObject: [NSNumber numberWithFloat: 1.0f]
afterDelay:1.5];
-(void) setUserAlphaNumber: (NSNumber*) number{
[txtUsername setAlpha: [number floatValue] ];
}
같은 방법으로 [NSNumber numberWithInt :] 등을 사용할 수 있으며 수신 방법에서 숫자를 [number int] 또는 [number double] 형식으로 변환 할 수 있습니다.
답변
블록은 갈 길이다. 복잡한 매개 변수, 유형 안전성을 가질 수 있으며 여기에있는 대부분의 이전 답변보다 훨씬 간단하고 안전합니다. 예를 들어 다음과 같이 작성할 수 있습니다.
[MONBlock performBlock:^{[obj setFrame:SOMETHING];} afterDelay:2];
블록을 사용하면 임의의 매개 변수 목록, 참조 개체 및 변수를 캡처 할 수 있습니다.
지원 구현 (기본) :
@interface MONBlock : NSObject
+ (void)performBlock:(void(^)())pBlock afterDelay:(NSTimeInterval)pDelay;
@end
@implementation MONBlock
+ (void)imp_performBlock:(void(^)())pBlock
{
pBlock();
}
+ (void)performBlock:(void(^)())pBlock afterDelay:(NSTimeInterval)pDelay
{
[self performSelector:@selector(imp_performBlock:)
withObject:[pBlock copy]
afterDelay:pDelay];
}
@end
예:
int main(int argc, const char * argv[])
{
@autoreleasepool {
__block bool didPrint = false;
int pi = 3; // close enough =p
[MONBlock performBlock:^{NSLog(@"Hello, World! pi is %i", pi); didPrint = true;} afterDelay:2];
while (!didPrint) {
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeInterval:0.1 sinceDate:NSDate.date]];
}
NSLog(@"(Bye, World!)");
}
return 0;
}
다른 예는 Michael의 대답 (+1)을 참조하십시오.