Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C equivalent of Java's BlockingQueue?

I'm just getting into iPhone development after many years doing Java development. I'm looking for the Objective-C equivalent to Java's BlockingQueue. Is there something like that?

In case I'm going about things the wrong way, here's what I'm trying to achieve:

I want to display, one at a time, chunks of data pulled from a network server. To keep the user from noticing network lag, I want to always have a few chunks of data pre-fetched. In Java-land, I'd use a thread-safe queue between my fetching thread and my display thread.

like image 960
William Pietri Avatar asked Dec 23 '22 10:12

William Pietri


2 Answers

Here's an implementation of a blocking queue with a queue and dequeue method. The expectation would be that one thread goes into a loop calling dequeueUnitOfWorkWaitingUntilDate: and processes units of work while a second thread is calling queueUnitOfWork:.

@interface MyBlockingQueue : NSObject {
    NSMutableArray *queue;
    NSConditionLock *queueLock;
}
- (id)dequeueUnitOfWorkWaitingUntilDate:(NSDate *)timeoutData;
- (void)queueUnitOfWork:(id)unitOfWork;
@end

enum {
    kNoWorkQueued = 0,
    kWorkQueued = 1
}

@implementation MyBlockingQueue
- (id)init {
    if ((self = [super init])) {
        queueLock = [[NSConditionLock alloc] initWithCondition:kNoWorkQueued];
        workItems = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)dealloc {
    [queueLock release];
    [workItems release];
    [super dealloc];
}

- (id)dequeueUnitOfWorkWaitingUntilDate:(NSDate *)timeoutDate {
    id unitOfWork = nil;
    if ([queueLock lockWhenCondition:kWorkQueued beforeDate:timeoutDate]) {
        unitOfWork = [[[queue objectAtIndex:0] retain] autorelease];
        [queue removeObjectAtIndex:0];
        [queueLock unlockWithCondition:([workItems count] ? kWorkQueued : kNoWorkQueued)];
    }
    return unitOfWork;
}

- (void)queueUnitOfWork:(id)unitOfWork {
    [queueLock lock];
    [queue addObject:unitOfWork];
    [queueLock unlockWithCondition:kWorkQueued];
}
@end
like image 121
Jon Hess Avatar answered Jan 06 '23 09:01

Jon Hess


You can simply spin off an NSOperation and post a notification when the data has come back (finished loading). Take a look at Dave Dribin's blog post on concurrency with NSOperation that shows how to encapsulate an NSURLConnection session:

http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/

If you are not talking about accessing a web service or site where NSURLConnection is appropriate, you can instead use Cocoa Async Socket if it's straight TCP/IP or UDP:

http://code.google.com/p/cocoaasyncsocket/

Best Regards,

like image 45
Matt Long Avatar answered Jan 06 '23 11:01

Matt Long