问题
My app uses NSInputStream like below:
inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[readStream open];
and delegate:
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
It works fine, but all other requests that i do, it queued until first is finished. I can do one per time and there is no way to do multiple concurrent requests.
There is a solution ? Thank you
This solution not work for me : https://stackoverflow.com/a/15346292/1376961
UPDATE: Was my server can't handle multiple connections from the same source.
回答1:
You will need to create your streams in separate threads to enable them to work simultaneously. I assume you have a method that sets up the inputStream you referred to:
- (void)openStreamInNewThread {
[NSThread detachNewThreadSelector:@selector(openStream) toTarget:self withObject:nil];
}
- (void)openStream {
NSInputStream *inputStream;
// stream setup
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
}
Note that [NSRunLoop currentRunLoop]
will return the runloop of the current thread. So you have the newly created stream running in a separate thread loading data simultaneously with other streams in their own threads.
回答2:
You can try to schedule each stream in its own run loop. Below is a refined method from the mock class designed to unit-test my POSInputStreamLibrary:
static const NSTimeInterval kRunLoopCycleInterval = 0.01f;
static const uint64_t kDispatchDeltaNanoSec = 250000000;
- (POSRunLoopResult)launchNSRunLoopWithStream:(NSInputStream *)stream delegate:(id<NSStreamDelegate>)streamDelegate {
stream.delegate = streamDelegate;
__block BOOL breakRunLoop = NO;
__block dispatch_semaphore_t doneSemaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
if ([stream streamStatus] == NSStreamStatusNotOpen) {
NSLog(@"%@: opening stream...", [NSThread currentThread]);
[stream open];
}
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopCycleInterval]] && !breakRunLoop)
{}
NSLog(@"%@: We are done!", [NSThread currentThread]);
dispatch_semaphore_signal(doneSemaphore);
});
POSRunLoopResult result = dispatch_semaphore_wait(doneSemaphore, dispatch_time(DISPATCH_TIME_NOW, kDispatchDeltaNanoSec)) == 0 ? POSRunLoopResultDone : POSRunLoopResultTimeout;
if (POSRunLoopResultTimeout == result) {
breakRunLoop = YES;
dispatch_semaphore_wait(doneSemaphore, DISPATCH_TIME_FOREVER);
}
return result;
}
回答3:
Each time I create a new NSInputStream, I add it to a block object, and then store the block object in an NSMutableArray.
I posted code that streams video from one iOS to another:
https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784
Build this app with Xcode 11; run it on two iOS 11 devices.
Touch the Camera icon on one of the two devices to start streaming live video.
If you don't have two devices, you can run the app in a simulator; however, stream from the real device only (the camera is not available on the simulator).
来源:https://stackoverflow.com/questions/33587831/ios-how-can-i-perform-multiple-nsinputstream