2010-02-16 7 views
1

저는 코코아 앱을 쓰고 있습니다. 응용 프로그램에는 소켓이 있으며 소켓이 읽을 수있게 될 때마다 소켓에서 데이터를 읽고 데이터를 처리하고 이에 따라 사용자 인터페이스를 업데이트하려고합니다. 내가 읽은 이벤트 체크를 메인 루프에 통합하고 싶다. 즉 소켓을 메인 루프에 연결하고 소켓이 읽을 수있게 될 때마다 메인 루프가 콜백을 호출하게하고 싶다.OS X : NSRunLoop으로 소켓 읽기 이벤트를 보는 방법?

내가 테스트 응용 프로그램을 작성했습니다,하지만 어떤 이유로 작동하지 않습니다

:이 애플리케이션은 로컬 호스트 포트 1234에서 수신하는데, 누군가가 서버에 연결하거나 할 때마다 데이터를 전송한다

#include <stdio.h> 
#include <Foundation/NSAutoReleasePool.h> 
#include <Foundation/NSRunLoop.h> 
#include <Foundation/NSPort.h> 

@interface MyDelegate : NSObject <NSPortDelegate> { 
} 
- (void)handlePortMessage:(NSPortMessage *)portMessage; 
@end 

@implementation MyDelegate 
- (void)handlePortMessage:(NSPortMessage *)portMessage { 
    printf("Haiz\n"); 
} 
@end 

int 
main() { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSSocketPort *server = [NSSocketPort alloc]; 
    MyDelegate *foo = [MyDelegate alloc]; 
    [server initWithTCPPort: 1234]; 
    [server setDelegate: foo]; 
    [[NSRunLoop mainRunLoop] addPort: server forMode: NSDefaultRunLoopMode]; 
    [[NSRunLoop mainRunLoop] run]; 
    [pool release]; 
    return 0; 
} 

서버에 응용 프로그램은 콘솔에 "Haiz"를 인쇄합니다. 그러나 애플 리케이션은 전혀 아무것도하지 않습니다. 소켓이 만들어지고 포트 1234로 텔넷 할 수 있지만 응용 프로그램이 콘솔에 아무 것도 인쇄하지 않습니다.

내가 뭘 잘못하고 있니? 문서에서

+0

다른 것들 중에서도 클래스에'alloc'을 보내지 만'init'을 인스턴스에 보내지 않습니다. MyDelegate 객체를 사용하여 이것을 완전히 잊어 버리는 이유는 동일한 메시지 표현식에서'alloc'과'init'을 항상 함께 사용해야하는 이유를 잘 보여줍니다 :'MyDelegate * foo = [[[MyDelegate alloc] init] autorelease];' 할당 한 객체를 릴리스해야합니다. 메모리 관리 규칙을 검토하십시오. http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

답변

1

:

NSSocketPort 객체는 분산 객체 연결을위한 엔드 포인트로 사용할 수 있습니다.

여기가하는 일이 아닙니다.

NSFileHandle (BSD 소켓 API의 소켓 파일 설명자 주변) 또는 (CFSocket). 이렇게하면 실행 루프에 소켓을 놓을 수 있습니다.

+0

NSFileHandle은 NSPort가 아니며 CFRunLoopSource가 없으므로 첨부 할 수 없습니다. 메인 루프로 – Hongli

+0

NSFileHandle은 NSPort가 아닙니다. NSPorts는 IPC를위한 것입니다. 해당 소켓에서 포트 메시지를받지 못하기 때문에 대리자 메서드가 호출되지 않습니다. 실행 루프에 연결하는 경우 파일 핸들에'acceptConnectionInBackgroundAndNotify' 메시지를 보내거나 대신 CFSocket을 사용하십시오. –

+0

FoundationKit이 CoreFoundation을 둘러싼 목적이있는 C 래퍼라는 인상을 받았다.하지만 이제는 CoreFoundation과 완전히 다른 점과 CoreFoundation으로 할 수있는 일이 있지만 FoundationKit에서는 그렇지 않은 것 같다. 내가 FoundationKit을 고집하려고하는 이유는 Objective C가 아닌 MacRuby에서 실제로 응용 프로그램을 작성하고 CoreFoundation API에서 기대하는 함수 포인터에 문제가 있기 때문입니다. – Hongli

0

당신이하고있는 방식대로 NSSocketPort을 사용하고 싶지만 소켓에서 연결을 허용하기 위해 NSFileHandle을 생성하십시오. 메인 쓰래드에서 콜백을 기대하는 것처럼, 처음에는 새로운 연결을 위해, 그런 다음 그 연결에 대한 데이터를 얻을 수 있습니다. 이 O'Reilly article을 사용하고 HTTP 내용 만 무시하십시오.