Objective-C等价于Java的BlockingQueue?

时间:2022-10-07 21:01:15

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?

在从事Java开发多年后,我刚刚开始从事iPhone开发。我正在寻找与Java的BlockingQueue等价的Objective-C。有这样的东西吗?

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.

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

3 个解决方案

#1


2  

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:

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

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

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:

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

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

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

Best Regards,

最好的问候,

#2


8  

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:.

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

#3


1  

I don't think such a thing exists natively - you're probably going to have to write your own class that maintains a queue of network objects. Your header might look something like:

我认为这种东西本身不存在——您可能需要编写自己的类来维护一个网络对象队列。你的标题可能看起来像:

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

@property(nonatomic,retain) NSArray *objects;

- (ServerData *)getNextChunk;

Then you can implement getNextChunk to pop and return the top object off your objects array, and if [objects count] is less than a certain value, launch a thread to fetch some more objects (probably using NSURLConnection with ObjcBlockingQueue being the delegate). You can also have that thread/connection launched inside an overridden init method to prefill the queue.

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

You might also want to think about adding a

你也可以考虑加入a

- (BOOL)isChunkAvailable;

method that will let your display thread know whether it can display something new right away or if it has to display a loading message. Depending on where you're displaying the data and how your app is structured, it may also be worth your while to make ObjcBlockingQueue a singleton class.

方法,它将让您的显示线程知道它是否可以显示新的内容,或者是否需要显示加载消息。根据显示数据的位置和应用程序的结构,让ObjcBlockingQueue成为单例类也是值得的。

#1


2  

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:

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

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

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:

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

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

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

Best Regards,

最好的问候,

#2


8  

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:.

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

#3


1  

I don't think such a thing exists natively - you're probably going to have to write your own class that maintains a queue of network objects. Your header might look something like:

我认为这种东西本身不存在——您可能需要编写自己的类来维护一个网络对象队列。你的标题可能看起来像:

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

@property(nonatomic,retain) NSArray *objects;

- (ServerData *)getNextChunk;

Then you can implement getNextChunk to pop and return the top object off your objects array, and if [objects count] is less than a certain value, launch a thread to fetch some more objects (probably using NSURLConnection with ObjcBlockingQueue being the delegate). You can also have that thread/connection launched inside an overridden init method to prefill the queue.

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

You might also want to think about adding a

你也可以考虑加入a

- (BOOL)isChunkAvailable;

method that will let your display thread know whether it can display something new right away or if it has to display a loading message. Depending on where you're displaying the data and how your app is structured, it may also be worth your while to make ObjcBlockingQueue a singleton class.

方法,它将让您的显示线程知道它是否可以显示新的内容,或者是否需要显示加载消息。根据显示数据的位置和应用程序的结构,让ObjcBlockingQueue成为单例类也是值得的。