gpt4 book ai didi

ios - ReactiveCocoa takeUntil 2 个可能的信号?

转载 作者:行者123 更新时间:2023-11-29 12:19:20 25 4
gpt4 key购买 nike

所以我已经成功地将一个按钮变成了一个可以改变标签的关闭和打开开关。

我还能够让它在发生这种情况时启动定时处理,并且它能够关闭定时过程。

无论如何,我需要关闭定时进程的方法,我想知道是否有办法在不使用一次性用品的情况下停止它。使用第二个 takeUntil 信号。

编辑我认为我试图做的有点误导让我展示我当前有效的解决方案。

-(RACSignal*) startTimer {
return [[RACSignal interval:1.0
onScheduler:[RACScheduler mainThreadScheduler]]
startWith:[NSDate date]];
}

-(void) viewWillAppear:(BOOL)animated {}

-(void) viewDidLoad {

self.tableView.delegate = self;
self.tableView.dataSource = self;

RACSignal* pressedStart = [self.start rac_signalForControlEvents:UIControlEventTouchUpInside];

@weakify(self);
RACSignal* textChangeSignal = [pressedStart map:^id(id value) {
@strongify(self);
return [self.start.titleLabel.text isEqualToString:@"Start"] ? @"Stop" : @"Start";
}];

// Changes the title
[textChangeSignal subscribeNext:^(NSString* text) {
@strongify(self);
[self.start setTitle:text forState:UIControlStateNormal];
}];

RACSignal* switchSignal = [[textChangeSignal map:^id(NSString* string) {
return [string isEqualToString:@"Stop"] ? @0 : @1;

}] filter:^BOOL(id value) {
NSLog(@"Switch %@",value);
return [value boolValue];
}];


[[self rac_signalForSelector:@selector(viewWillAppear:)]
subscribeNext:^(id x) {


}];

static NSInteger t = 0;
// Remake's it self once it is on finished.
self.disposable = [[[textChangeSignal filter:^BOOL(NSString* text) {
return [text isEqualToString:@"Stop"] ? [@1 boolValue] : [@0 boolValue];
}]
flattenMap:^RACStream *(id value) {
NSLog(@"Made new Sheduler");
@strongify(self);
return [[self startTimer] takeUntil:switchSignal];
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
@strongify(self);
t = t + 1;
NSLog(@"%zd",t);

[self updateTable];
}];

[[self rac_signalForSelector:@selector(viewWillDisappear:)] subscribeNext:^(id x) {
NSLog(@"viewWillAppear Dispose");
[self.disposable dispose];
}];

}


-(BOOL) isGroupedExcercisesLeft {
BOOL isGroupedLeft = NO;
for (int i =0;i < [self.excercises count]; i++) {
Excercise* ex = [self.excercises objectAtIndex:i];
if(ex.complete == NO && ex.grouped == YES) {
isGroupedLeft = YES;
break;
}
}
return isGroupedLeft;
}

-(void) updateTable {

// Find the
NSInteger nextRow;

if (([self.excercises count] > 0 || self.excercises !=nil) && [self isGroupedExcercisesLeft]) {

for (int i =0;i < [self.excercises count]; i++) {

Excercise* ex = [self.excercises objectAtIndex:i];
if(ex.complete == NO && ex.grouped == YES) {
nextRow = i;
break;
}

}

NSIndexPath* path = [NSIndexPath indexPathForItem:nextRow inSection:0];
NSArray* indexPath = @[path];
// update //

Excercise* ex = [self.excercises objectAtIndex:nextRow];
[self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
if (ex.seconds <= 0) {
RLMRealm* db = [RLMRealm defaultRealm];
[db beginWriteTransaction];
ex.complete = YES;
[db commitWriteTransaction];
}
else {
// Update Seconds
RLMRealm* db = [RLMRealm defaultRealm];
[db beginWriteTransaction];
ex.seconds = ex.seconds - 1000;
NSLog(@"Seconds: %zd",ex.seconds);
[db commitWriteTransaction];
// Update table
[self.tableView reloadRowsAtIndexPaths:indexPath withRowAnimation:UITableViewRowAnimationNone];
}


} else {
NSLog(@"Done");

SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:@"Deskercise" andMessage:@"Excercises Complete"];
[alertView addButtonWithTitle:@"Ok"
type:SIAlertViewButtonTypeDefault
handler:^(SIAlertView *alert) {

}];

alertView.transitionStyle = SIAlertViewTransitionStyleBounce;
[alertView show];
NSLog(@"Dispose");
[self.disposable dispose];

}

}

最佳答案

使用 takeUntil:self.completeSignal 的问题是当你改变completeSignal到另一个值,它不会传递给任何已经在等待 completeSignal 变量的函数之前持有。

- (RACSignal*) startTimer {
@weakify(self)
return [[[RACSignal interval:1.0
onScheduler:[RACScheduler mainThreadScheduler]]
startWith:[NSDate date]]
takeUntil:[[self.start rac_signalForControlEvents:UIControlEventTouchUpInside]
merge:[[RACObserve(self, completeSignal) skip:1] flattenMap:
^RACStream *(RACSignal * signal) {
@strongify(self)
return self.completeSignal;
}]]
];
}

信号现在正在观察和变平completeSignal ,这将产生预期的效果。 takeUntil: 忽略未发送下一个事件而完成的信号, 所以使用 self.completedSignal = [RACSignal return:nil] , 它发送一个下一个事件然后完成。

但是,这段代码并不理想,让我们看看更好的解决方案。

@property (nonatomic, readwrite) RACSubject * completeSignal;

- (RACSignal*) startTimer {
return [[[RACSignal interval:1.0
onScheduler:[RACScheduler mainThreadScheduler]]
startWith:[NSDate date]]
takeUntil:[[self.start rac_signalForControlEvents:UIControlEventTouchUpInside]
merge:self.completeSignal]
];
}
- (void) viewDidLoad {
[super viewDidLoad];
self.completeSignal = [RACSubject subject];
self.tableView.delegate = self;
self.tableView.dataSource = self;

RACSignal * pressedStart = [self.start rac_signalForControlEvents:UIControlEventTouchUpInside];

@weakify(self);
RACSignal* textChangeSignal = [[pressedStart startWith:nil] scanWithStart:@"Stop" reduce:^id(id running, id next) {
return @{@"Start":@"Stop", @"Stop":@"Start"}[running];
}];

[self.start
rac_liftSelector:@selector(setTitle:forState:)
withSignals:textChangeSignal, [RACSignal return:@(UIControlStateNormal)], nil];

[[[pressedStart flattenMap:^RACStream *(id value) { //Using take:1 so that it doesn't get into a feedback loop
@strongify(self);
return [self startTimer];
}] scanWithStart:@0 reduce:^id(NSNumber * running, NSNumber * next) {
return @(running.unsignedIntegerValue + 1);
}] subscribeNext:^(id x) {
@strongify(self);
[self updateTable];
NSLog(@"%@", x);
}];
}

- (void) updateTable {
//If you uncomment these then it'll cause a feedback loop for the signal that calls updateTable

//[self.start sendActionsForControlEvents:UIControlEventTouchUpInside];
//[self.completeSignal sendNext:nil];
if ([self.excercises count] > 0 || self.excercises !=nil) {
} else {
}
}

让我们浏览一下更改列表:

  • completeSignal现在是 RACSubject(手动控制的 RACSignal)。
  • 为了纯度和摆脱 @weakify指令,textChangeSignal现在使用得心应手的 scanWithStart:reduce:方法,它允许您访问累加器(这适用于处理递增或递减数字的方法)。
  • start的文本现在被 rac_liftSelector 更改了函数,它接受 RACSignals 并在所有信号都触发时解包它们。
  • 你的 flattenMap:替换 pressedStart[self startTimer]现在使用 scanWithStart:reduce ,这是一种更实用的计数方式。

我不确定您是否通过 updateTable 进行测试包含完成信号,但它肯定会导致您的 flattenMap: 出现逻辑问题的 pressedButton ,由此产生的反馈循环最终会在堆栈溢出时使程序崩溃。

关于ios - ReactiveCocoa takeUntil 2 个可能的信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31092146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com