Objective-C эквивалент Java в BlockingQueue? - PullRequest
4 голосов
/ 06 августа 2009

Я только начинаю разработку iPhone после многих лет разработки Java. Я ищу Objective-C, эквивалентный Java BlockingQueue . Есть ли что-то подобное?

В случае, если я поступаю неправильно, вот что я пытаюсь достичь:

Я хочу отображать по одной порции данных, извлеченных с сетевого сервера. Чтобы пользователь не заметил отставание в сети, я хочу всегда иметь несколько предварительно загруженных фрагментов данных. В Java-земле я бы использовал потокобезопасную очередь между потоком извлечения и потоком отображения.

Ответы [ 3 ]

8 голосов
/ 06 августа 2009

Вот реализация блокировки очереди с помощью метода очереди и очереди. Ожидается, что один поток входит в цикл, вызывающий 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
2 голосов
/ 06 августа 2009

Вы можете просто отключить NSOperation и опубликовать уведомление, когда данные вернутся (законченная загрузка). Взгляните на блог Дэйва Дрибина о параллелизме с NSOperation, в котором показано, как инкапсулировать сеанс NSURLConnection:

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

Если вы не говорите о доступе к веб-службе или сайту, где подходит NSURLConnection, вы можете вместо этого использовать Cocoa Async Socket, если это прямой TCP / IP или UDP:

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

С наилучшими пожеланиями,

1 голос
/ 06 августа 2009

Я не думаю, что такая вещь существует изначально - вам, вероятно, придется написать свой собственный класс, который поддерживает очередь сетевых объектов. Ваш заголовок может выглядеть примерно так:

@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 одноэлементным классом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...