Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
595 views
in Technique[技术] by (71.8m points)

objective c - NSStream and Sockets, NSStreamDelegate methods not being called

I've followed the guide Setting Up Socket Streams and have effectively duplicated that code in my class. No matter what I try the delegate methods just don't seem to get called.

In the header file I have (basically):

@interface myClass : NSObject <NSStreamDelegate> {
    NSInputStream *inputStream;
    NSOutputStream *outputStream;
}
- (void)connect;
@end;

The connect method:

- (void)connect {
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)@"host.example.com", 1234, &readStream, &writeStream);

    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
}

Also tried using CFStreamCreatePairWithSocketToCFHost() and [NSStream getStreamsToHost:port:inputStream:outputStream: - all with exactly the same result.

I've set a breakpoint at the beginning of the connect method, stepped through every line and every pointer is valid and seems to point to the correct object.

In GDB, after the setDelegate calls, po [inputStream delegate] prints <myClass: 0x136380> as expected, so it has set the delegate correctly.

For the life of me I can't work out why it refuses to call the stream:handleEvent: method on my class:

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    NSLog(@"got an event");
}

Hopefully I've missed something really simple and obvious and a second pair of eyes can spot my mistake.

Thanks in advance to anyone who has the patience and taken the time to read this far!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the lines like this:

[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Instead of using [NSRunLoop currentRunLoop] I changed it to [NSRunLoop mainRunLoop].

EDIT 2011-05-30:

The reason this did not work is because I was setting up the sockets in a background thread via +[NSThread detachNewThreadSelector:toTarget:withObject:].

Doing it that way created a new run loop, which after reading the run loop developer documentation I discovered that you need to tell the NSRunLoop to run manually.

Running it in the same run loop as the main thread was fine on performance, though I was able to squeeze a bit more performance out by writing a wrapper class and running all network I/O on a background thread.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...