[objective-c] Objective-C에서 콜백을 수행하는 방법

Objective-C에서 콜백 기능을 수행하는 방법은 무엇입니까?

완성 된 몇 가지 예제를보고 싶습니다. 이해해야합니다.



답변

일반적으로 목표 C의 콜백은 델리게이트로 수행됩니다. 다음은 사용자 지정 대리자 구현의 예입니다.


헤더 파일 :

@interface MyClass : NSObject {
    id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end

@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end

구현 (.m) 파일

@implementation MyClass
- (void)setDelegate:(id)aDelegate {
    delegate = aDelegate; /// Not retained
}

- (void)doSomething {
    [delegate myClassWillDoSomething:self];
    /* DO SOMETHING */
    [delegate myClassDidDoSomething:self];
}
@end

이것은 일반적인 접근 방식을 보여줍니다. 콜백 메서드의 이름을 선언하는 NSObject에 범주를 만듭니다. NSObject는 실제로 이러한 메서드를 구현하지 않습니다. 이러한 유형의 범주를 비공식 프로토콜이라고합니다. 많은 개체가 이러한 메서드를 구현할 수 있다는 의미입니다. 선택 자의 형식 서명을 전달하는 방법입니다.

다음으로 일부 개체는 “MyClass”의 대리자가되고 MyClass는 대리자의 대리자 메서드를 적절하게 호출합니다. 델리게이트 콜백이 선택 사항 인 경우 일반적으로 “if ([delegate respondsToSelector : @selector (myClassWillDoSomething :)) {“과 같이 디스패치 사이트에서이를 보호합니다. 내 예에서 대리자는 두 메서드를 모두 구현해야합니다.

비공식 프로토콜 대신 @protocol로 정의 된 공식 프로토콜을 사용할 수도 있습니다. 그렇게하면 델리게이트 setter의 유형을 변경하고 인스턴스 변수를 ” id <MyClassDelegate>“대신 ” id“로 변경합니다.

또한 대리인이 유지되지 않음을 알 수 있습니다. 이는 일반적으로 “MyClass”인스턴스를 “소유”하는 개체가 일반적으로 대리자이기 때문에 수행됩니다. MyClass가 델리게이트를 유지했다면 유지주기가있을 것입니다. MyClass 인스턴스가 있고 약한 백 포인터이기 때문에 대리자 참조를 지우는 대리자 인 클래스의 dealloc 메서드에서 좋은 생각입니다. 그렇지 않으면 MyClass 인스턴스를 유지하는 것이 있으면 매달린 포인터가 생깁니다.


답변

완전성을 위해 StackOverflow RSS가 무작위로 질문을 부활 시켰으므로 다른 (최신) 옵션은 블록을 사용하는 것입니다.

@interface MyClass: NSObject
{
    void (^_completionHandler)(int someParameter);
}

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler;
@end


@implementation MyClass

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler
{
    // NOTE: copying is very important if you'll call the callback asynchronously,
    // even with garbage collection!
    _completionHandler = [handler copy];

    // Do stuff, possibly asynchronously...
    int result = 5 + 3;

    // Call completion handler.
    _completionHandler(result);

    // Clean up.
    [_completionHandler release];
    _completionHandler = nil;
}

@end

...

MyClass *foo = [[MyClass alloc] init];
int x = 2;
[foo doSomethingWithCompletionHandler:^(int result){
    // Prints 10
    NSLog(@"%i", x + result);
}];


답변

다음은 델리게이트의 개념을 배제하고 원시 콜백을 수행하는 예입니다.

@interface Foo : NSObject {
}
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector;
@end

@interface Bar : NSObject {
}
@end

@implementation Foo
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector {
    /* do lots of stuff */
    [object performSelector:selector withObject:self];
}
@end

@implementation Bar
- (void)aMethod {
    Foo *foo = [[[Foo alloc] init] autorelease];
    [foo doSomethingAndNotifyObject:self withSelector:@selector(fooIsDone:)];
}

- (void)fooIsDone:(id)sender {
    NSLog(@"Foo Is Done!");
}
@end

일반적으로-[Foo doSomethingAndNotifyObject : withSelector :] 메서드는 비동기식이므로 여기보다 콜백이 더 유용합니다.


답변

이 질문을 최신 상태로 유지하기 위해 iOS 5.0의 ARC 도입은 Blocks를 사용하여 더욱 간결하게 수행 할 수 있음을 의미합니다 .

@interface Robot: NSObject
+ (void)sayHi:(void(^)(NSString *))callback;
@end

@implementation Robot
+ (void)sayHi:(void(^)(NSString *))callback {
    // Return a message to the callback
    callback(@"Hello to you too!");
}
@end

[Robot sayHi:^(NSString *reply){
  NSLog(@"%@", reply);
}];

Objective-C의 블록 구문을 잊어 버린 경우 항상 F **** ng 블록 구문 이 있습니다.


답변

콜백 : Objective C에는 4 가지 유형의 콜백이 있습니다.

  1. 선택기 유형 : NSTimer, UIPangesture가 Selector 콜백의 예입니다. 매우 제한된 코드 실행에 사용됩니다.

  2. 위임 유형 : 일반적이며 Apple 프레임 워크에서 가장 많이 사용됩니다. UITableViewDelegate, NSNURLConnectionDelegate. 일반적으로 서버에서 비동기식으로 많은 이미지 다운로드를 표시하는 데 사용됩니다.

  3. NSNotifications : NotificationCenter는 이벤트 발생시 많은 수취인에게 알림을 제공하는 Objective C의 기능 중 하나입니다.
  4. 블록 : 블록은 Objective C 프로그래밍에서 더 일반적으로 사용됩니다. 훌륭한 기능이며 코드 덩어리를 실행하는 데 사용됩니다. 이해하기 위해 튜토리얼을 참조 할 수도 있습니다. 블록 튜토리얼

다른 답변이 있으면 알려주십시오. 감사하겠습니다.


답변