ant*_*014 3 synchronization objective-c synchronized grand-central-dispatch ios
我试图将我的所有任务从不同的NSTimer分配到一个队列,因此任务可以逐个完成.任务完成后,我将通过另一个班级的代表获得通知.
更新:任务
我的应用程序正在尝试与其他设备通信,但该设备一次只能接受一个任务,因此我每次都必须向其发送一个任务,并确保我已收到表明任务已被执行的确认完成后,我可以要求它做下一个任务.
我尝试使用BOOL来控制IDLE,SENDING状态.但我无法使其同步,即使我使用以下代码:
@property (atomic) BOOL ready2Send;
@end
@implementation ...
@synthesize ready2Send = _ready2Send;
- (BOOL)ready2Send
{
BOOL tmp;
@synchronized(self) {
tmp = _ready2Send;
}
return tmp;
}
- (void)setReady2Send:(BOOL)ready2Send
{
@synchronized(self){
if (_ready2Send != ready2Send) {
_ready2Send = ready2Send;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,总有一种情况,这个属性将一直保持不死.
所以我开始考虑使用队列,也许是dispatch_queue.我的UIViewController需要一个队列.
我的问题是:
感谢你.
假设您的"与其他设备通信"是异步发生的,有两种方法:
在完成一项任务后,启动下一个任务.
例如,您可能有NSMutableArray一些项目要发送到其他设备:
@property (nonatomic, strong) NSMutableArray *itemsToSend;
Run Code Online (Sandbox Code Playgroud)
一旦你填充了这个数组,开始这个过程,你可能会做一个
[self sendItem:itemsToSend[0]];
Run Code Online (Sandbox Code Playgroud)
当它完成后,您可以执行以下操作:
[itemsToSend removeObjectAtIndex:0];
if ([itemsToSend count] > 0)
{
[self sendItem:itemsToSend[0];
}
Run Code Online (Sandbox Code Playgroud)更优雅(虽然更复杂)的方法是子类化NSOperation(请参阅定义自定义操作).你可以,例如:
@interface TaskOperation ()
@property (nonatomic, readwrite, getter = isExecuting) BOOL executing;
@property (nonatomic, readwrite, getter = isFinished) BOOL finished;
@end
@implementation TaskOperation
@synthesize finished = _finished;
@synthesize executing = _executing;
- (id)init
{
self = [super init];
if (self) {
_executing = NO;
_finished = NO;
}
return self;
}
- (void)start
{
if (self.isCancelled) {
self.finished = YES;
return;
}
self.executing = YES;
// initiate your time consuming process here
// when it's done, have it call `[self complete]`
}
- (void)complete
{
self.executing = NO;
self.finished = YES;
}
- (void)setExecuting:(BOOL)executing
{
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)setFinished:(BOOL)finished
{
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
- (BOOL)isConcurrent
{
return NO;
}
@end
Run Code Online (Sandbox Code Playgroud)
启动这些发送请求的进程可以执行以下操作:
// create a serial queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
TaskOperation *operation;
// create and submit the three operations
operation = [[TaskOperation alloc] init ...];
[queue addOperation:operation];
operation = [[TaskOperation alloc] init ...];
[queue addOperation:operation];
operation = [[TaskOperation alloc] init ...];
[queue addOperation:operation];
Run Code Online (Sandbox Code Playgroud)
注意,我在init方法之后添加了省略号,因为通常在这种情况下,您编写自己的自定义init方法,该方法传递操作完成其任务所需的任何信息(例如,正在传输的内容的名称,可能在何处传输等等).
但希望你能得到这个想法.您定义了一个操作类来执行您的任务,然后您可以创建一个串行队列并提交您的任务,它们将按顺序一个接一个地执行.
如果您的"与其他设备通信"进程同步发生,那么它就比这更容易了.(但话又说回来,如果它同步发生,你可能不会一直在搞定时器和状态标志.)
| 归档时间: |
|
| 查看次数: |
2190 次 |
| 最近记录: |