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成为单例类也是值得的。