Objective-C相当于Java的BlockingQueue?

时间:2009-08-05 23:29:30

标签: iphone objective-c multithreading

我正在进行Java开发多年后进入iPhone开发。我正在寻找与Java BlockingQueue等效的Objective-C。有类似的东西吗?

如果我以错误的方式处理事情,这就是我想要实现的目标:

我想一次一个地显示从网络服务器中提取的数据块。为了防止用户注意网络延迟,我希望总是预先获取一些数据块。在Java-land中,我在我的提取线程和显示线程之间使用了一个线程安全的队列。

3 个答案:

答案 0 :(得分:8)

这是带有队列和出队方法的阻塞队列的实现。期望是一个线程进入一个调用dequeueUnitOfWorkWaitingUntilDate的循环:并在第二个线程调用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

答案 1 :(得分:2)

您可以简单地关闭NSOperation并在数据返回时发布通知(完成加载)。看看Dave Dribin关于NSOperation的并发性的博客文章,该文章展示了如何封装NSURLConnection会话:

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

如果您不是在谈论访问适合NSURLConnection的Web服务或站点,那么如果它是直接的TCP / IP或UDP,您可以使用Cocoa Async Socket:

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

最诚挚的问候,

答案 2 :(得分:1)

我认为这样的东西本身并不存在 - 你可能不得不编写自己的类来维护网络对象的队列。您的标题可能类似于:

@interface ObjcBlockingQueue : NSObject {
    // The objects that you're holding onto
    NSArray *objects;
}

@property(nonatomic,retain) NSArray *objects;

- (ServerData *)getNextChunk;

然后你可以实现getNextChunk弹出并返回objects数组中的顶级对象,如果[objects count]小于某个值,则启动一个线程来获取更多对象(可能使用NSURLConnection,ObjcBlockingQueue是委托)。您还可以在重写的init方法中启动该线程/连接以预填充队列。

您可能还想考虑添加

- (BOOL)isChunkAvailable;

方法,让您的显示线程知道它是否可以立即显示新内容或是否必须显示加载消息。根据您显示数据的位置以及应用程序的结构,将ObjcBlockingQueue设为单一类可能也值得您花些时间。