source

NSInvocation for Dummies?

manysource 2023. 4. 10. 22:01

NSInvocation for Dummies?

는 어떤 요?NSInvocation? 은은소 은??

특히 다음 코드(Mac OS X용 코코아 프로그래밍, 3rd Edition)의 작동 방식을 이해하는 데 문제가 있지만 튜토리얼 샘플과는 별도로 개념을 적용할 수도 있습니다.코드:

- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
    NSLog(@"adding %@ to %@", p, employees);
    // Add inverse of this operation to undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
    if (![undo isUndoing])
        [undo setActionName:@"Insert Person"];
    
    // Finally, add person to the array
    [employees insertObject:p atIndex:index];
}

- (void)removeObjectFromEmployeesAtIndex:(int)index
{
    Person *p = [employees objectAtIndex:index];
    NSLog(@"removing %@ from %@", p, employees);
    // Add inverse of this operation to undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self] insertObject:p
                                       inEmployeesAtIndex:index];
    if (![undo isUndoing])
        [undo setActionName:@"Delete Person"];
    
    // Finally, remove person from array
    [employees removeObjectAtIndex:index];
}

알것 같아BTW, i i i i i i ib i, i i, i i, i i, i i, i i, i i, i i, i i, i i, i i i, i?employees는 입니다.NSArrayPerson★★★★★★★★★★★★★★★★★★」

가 되는 것.NET guy, 나는 Obj-C와 코코아에 대한 생소한 개념을 대략 비슷한 개념과 연관시키려 한다.NET 개념이것은 와 유사합니까?NET의 대리자 컨셉이지만 입력되지 않았습니까?

이 책에서는 100% 명확하지 않기 때문에, 심플한(-ish) 예제의 기본적인 개념을 이해하는 것을 목표로, 진정한 Cocoa/Obj-C 전문가로부터 보충적인 것을 찾고 있습니다.저는 그 지식을 독립적으로 적용할 수 있기를 정말 바라고 있습니다. 9장까지는 그렇게 하는 데 어려움이 없었습니다.하지만 지금은...

Apple의 NSInvocation 클래스 레퍼런스에 따르면:

NSInvocation는 스태틱하게 렌더링된 Objective-C 메시지입니다.즉, 오브젝트로 변환된 액션입니다.

그리고 좀 더 자세히 설명하겠습니다.

메시지의 개념은 목적 c 철학의 중심이다.메서드를 호출하거나 일부 개체의 변수에 액세스할 때마다 메시지를 보냅니다. NSInvocation는, 다른 시점에서 오브젝트에 메시지를 송신하거나 같은 메시지를 여러 번 송신하는 경우에 편리합니다. NSInvocation그럼, 송신하는 메시지를 기술해, 나중에 그 메시지를 호출할 수 있습니다(실제로 타겟오브젝트에 송신).


예를 들어 배열에 문자열을 추가한다고 가정합니다. 보내요.addObject:하다

[myArray addObject:myString];

그럼 이번에는 ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴNSInvocation다른 시점에서 이 메시지를 송신하려면 , 다음과 같이 하십시오.

먼저 '아,아,아,아,아,아,아,아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 네.NSInvocation에서 NSMutableArray의 »addObject:★★★★★★★★★★★★★★★★★★:

NSMethodSignature * mySignature = [NSMutableArray
    instanceMethodSignatureForSelector:@selector(addObject:)];
NSInvocation * myInvocation = [NSInvocation
    invocationWithMethodSignature:mySignature];

그런 다음 메시지를 보낼 개체를 지정합니다.

[myInvocation setTarget:myArray];

해당 개체로 보낼 메시지를 지정하십시오.

[myInvocation setSelector:@selector(addObject:)];

그리고 그 메서드에 대한 인수를 입력합니다.

[myInvocation setArgument:&myString atIndex:2];

오브젝트 인수는 포인터로 전달해야 합니다.Ryan McCuaig씨가 지적해 주셔서 감사합니다.자세한 것은 Apple의 메뉴얼을 참조해 주세요.

이 시점에서myInvocation는, 송신 가능한 메시지를 나타내는 완전한 오브젝트입니다.실제로 메시지를 보내려면 다음과 같이 전화해야 합니다.

[myInvocation invoke];

이 마지막 단계에서는 메시지가 전송되어 기본적으로 실행됩니다.[myArray addObject:myString];.

이메일을 보내는 것처럼 생각하세요.새로운 이메일을 엽니다(NSInvocation오브젝트), 송신지(오브젝트)의 주소를 입력하고, 수신자의 메시지를 입력합니다(메시지를 입력합니다).selector및 인수)를 클릭한 다음 "전송"(콜)을 클릭합니다.invoke).

자세한 내용은 NSInvocation 사용을 참조하십시오.위가 동작하지 않는 경우는, 「NSInvocation의 사용」을 참조해 주세요.


NSUndoManager사용하다NSInvocation명령어를 리버스할 수 있도록 오브젝트를 설정합니다.기본적으로, 당신이 하고 있는 것은,NSInvocation오브젝트: "이봐, 내가 방금 한 일을 되돌리고 싶으면 이 메시지를 이 오브젝트에 보내, 이 인수들과 함께."당신이 주는 건NSInvocation에 반대하다NSUndoManager이 오브젝트를 실행 취소 가능한 액션 배열에 추가합니다.사용자가 "Undo"를 호출하면NSUndoManager단순히 어레이 내의 최신 액션을 검색하고 저장된 액션을 호출합니다.NSInvocation오브젝트를 지정하여 필요한 액션을 수행합니다.

자세한 내용은 실행 취소 작업 등록을 참조하십시오.

다음으로 NSInvocation의 동작 예를 나타냅니다.

- (void)hello:(NSString *)hello world:(NSString *)world
{
    NSLog(@"%@ %@!", hello, world);

    NSMethodSignature *signature  = [self methodSignatureForSelector:_cmd];
    NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setTarget:self];                    // index 0 (hidden)
    [invocation setSelector:_cmd];                  // index 1 (hidden)
    [invocation setArgument:&hello atIndex:2];      // index 2
    [invocation setArgument:&world atIndex:3];      // index 3

    // NSTimer's always retain invocation arguments due to their firing delay. Release will occur when the timer invalidates itself.
    [NSTimer scheduledTimerWithTimeInterval:1 invocation:invocation repeats:NO];
}

호출 시 -[self hello:@"Hello" world:@"world"];- 방법은 다음과 같습니다.

  • "Hello world!"라고 인쇄합니다.
  • NSMethodSignature를 만듭니다.
  • NSInvocation을 작성 및 입력하여 호출합니다.
  • NSTimer에 NSInvocation 전달
  • 타이머는 (약)1초 후에 기동해, 원래의 인수로 메서드를 재호출합니다.
  • 따라하다.

최종적으로는, 다음과 같은 인쇄물을 얻을 수 있습니다.

2010-07-11 17:48:45.262 Your App[2523:a0f] Hello world!
2010-07-11 17:48:46.266 Your App[2523:a0f] Hello world!
2010-07-11 17:48:47.266 Your App[2523:a0f] Hello world!
2010-07-11 17:48:48.267 Your App[2523:a0f] Hello world!
2010-07-11 17:48:49.268 Your App[2523:a0f] Hello world!
2010-07-11 17:48:50.268 Your App[2523:a0f] Hello world!
2010-07-11 17:48:51.269 Your App[2523:a0f] Hello world!
...

물론 타깃 오브젝트는self는 NSTimer가 NSInvocation을 전송하기 위해 계속 존재해야 합니다.예를 들어 Singleton 객체 또는 애플리케이션 기간 동안 존재하는 AppDelegate가 있습니다.


갱신:

위에서 설명한 바와 같이 NSTimer에 인수로서 NSInvocation을 전달하면 NSTimer는 NSInvocation의 모든 인수를 자동으로 유지합니다.

NSInvocation을 인수로 NSTimer에 전달하지 않고 NSTimer를 한동안 유지할 계획인 경우 NSInvocation을 호출해야 합니다.-retainArguments되어 최종적으로 가 크래시될 수 있습니다.그렇지 않으면 해당 인수가 호출되기 전에 할당 해제되어 코드가 크래시될 수 있습니다.을 사용하다

NSMethodSignature *signature  = ...;
NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];
id                arg1        = ...;
id                arg2        = ...;

[invocation setTarget:...];
[invocation setSelector:...];
[invocation setArgument:&arg1 atIndex:2];
[invocation setArgument:&arg2 atIndex:3];

[invocation retainArguments];  // If you do not call this, arg1 and arg2 might be deallocated.

[self someMethodThatInvokesYourInvocationEventually:invocation];

당신은 훨씬 더 좋은 이 도서관을 사용해 볼 수 있다: http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

NSInvocation을 사용하여 다양한 메서드유형을 호출하는 간단한 예를 작성합니다.

obj_msgSend를 사용하여 여러 매개 변수를 호출하는 데 문제가 발생했습니다.

https://github.com/clearbrian/NSInvocation_Runtime

언급URL : https://stackoverflow.com/questions/313400/nsinvocation-for-dummies