RxSwift rx_text双向绑定崩溃



我正在尝试使用示例中的<->运算符进行简单的双向绑定。

import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
    let textview = UITextView()
    let testVar = Variable("")
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(textview)
        textview.frame = view.bounds
        textview.backgroundColor = UIColor.whiteColor()
        textview.rx_text <-> testVar
    }
}
infix operator <-> {
}
func <-> <T>(property: ControlProperty<T>, variable: Variable<T>) -> Disposable {
    let bindToUIDisposable = variable.asObservable()
        .bindTo(property)
    let bindToVariable = property
        .subscribe(onNext: { n in
            variable.value = n
            }, onCompleted:  {
                bindToUIDisposable.dispose()
        })
    return StableCompositeDisposable.create(bindToUIDisposable, bindToVariable)
}

编辑此文本视图会导致异常,我不确定如何解决它。

2016-02-29 18:44:23.322 TestRX[71117:38702571] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[NSLayoutManager _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] *** attempted layout while textStorage is editing.  It is not valid to cause the layoutManager to do layout while the textStorage is editing (ie the textStorage has been sent a beginEditing message without a matching endEditing.)'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010cd64e65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010eaa4deb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010cd64d9d +[NSException raise:format:] + 205
    3   UIFoundation                        0x000000011444636e -[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 531
    4   UIFoundation                        0x000000011444da73 _NSFastFillAllLayoutHolesForGlyphRange + 1467
    5   UIFoundation                        0x000000011444b01a -[NSLayoutManager(NSPrivate) _rectArrayForRange:withinSelectionRange:rangeIsCharRange:singleRectOnly:fullLineRectsOnly:inTextContainer:rectCount:rangeWithinContainer:glyphsDrawOutsideLines:rectArray:rectArrayCapacity:] + 822
    6   UIFoundation                        0x000000011444e488 -[NSLayoutManager(NSPrivate) _rectArrayForRange:withinSelectionRange:rangeIsCharRange:singleRectOnly:fullLineRectsOnly:inTextContainer:rectCount:rangeWithinContainer:glyphsDrawOutsideLines:] + 117
    7   UIFoundation                        0x0000000114486f42 -[NSLayoutManager rectArrayForCharacterRange:withinSelectedCharacterRange:inTextContainer:rectCount:] + 80
    8   UIKit                               0x000000010df3a801 -[_UITextContainerView updateInsertionPointStateAndRestartTimer:] + 311
    9   UIFoundation                        0x0000000114452daf -[NSLayoutManager(NSPrivate) _invalidateLayoutForExtendedCharacterRange:isSoft:invalidateUsage:] + 2118
    10  UIKit                               0x000000010df23a98 -[UITextView setAttributedText:] + 950
    11  UIKit                               0x000000010df2bc95 -[UITextView setText:] + 188
    12  RxCocoa                             0x000000010c805fc7 _TFFE7RxCocoaCSo10UITextViewg7rx_textGVS_15ControlPropertySS_U0_FTS0_SS_T_ + 119
    13  RxCocoa                             0x000000010c806027 _TTRXFo_oCSo10UITextViewoSS_dT__XFo_oS_iSS_dT__ + 55
    14  RxCocoa                             0x000000010c7f300b _TFC7RxCocoa17UIBindingObserver2onu0_Rq_Ss9AnyObject_fGS0_q_q0__FGO7RxSwift5Eventq0__T_ + 747
    15  RxCocoa                             0x000000010c7f342f _TTWu0_Rq_Ss9AnyObject_GC7RxCocoa17UIBindingObserverq_q0__7RxSwift12ObserverTypeS0_FS3_2onuRq_S3__fq_FGOS2_5Eventqq_S3_1E_T_ + 63
    16  RxSwift                             0x000000010c8fbd31 _TPA + 113
    17  RxSwift                             0x000000010c8fb933 _TFV7RxSwift11AnyObserver2onurfGS0_q__FGOS_5Eventq__T_ + 387
    18  RxCocoa                             0x000000010c7ac198 _TFV7RxCocoa15ControlProperty2onurfGS0_q__FGO7RxSwift5Eventq__T_ + 1000
    19  RxCocoa                             0x000000010c7ac56c _TTWurGV7RxCocoa15ControlPropertyq__7RxSwift12ObserverTypeS_FS2_2onuRq_S2__fq_FGOS1_5Eventqq_S2_1E_T_ + 92
    20  RxSwift                             0x000000010c8fbd31 _TPA + 113
    21  RxSwift                             0x000000010c8fb933 _TFV7RxSwift11AnyObserver2onurfGS0_q__FGOS_5Eventq__T_ + 387
    22  RxSwift                             0x000000010c8fba44 _TTWurGV7RxSwift11AnyObserverq__S_12ObserverTypeS_FS1_2onuRq_S1__fq_FGOS_5Eventqq_S1_1E_T_ + 68
    23  RxSwift                             0x000000010c903e35 _TFeRq_7RxSwift12ObserverType_S_VS_3Bag2onuRq_S0__fGS1_q__FGOS_5Eventqq_S0_1E_T_ + 1141
    24  RxSwift                             0x000000010c90dbb3 _TFC7RxSwift15BehaviorSubject16_synchronized_onurfGS0_q__FGOS_5Eventq__T_ + 3747
    25  RxSwift                             0x000000010c90cc7c _TFC7RxSwift15BehaviorSubject2onurfGS0_q__FGOS_5Eventq__T_ + 380
    26  RxSwift                             0x000000010ca0fbfd _TFC7RxSwift8Variables5valueq_ + 365
    27  TestRX                              0x000000010c6fcc0b _TFZF6TestRXoi3lsgurFTGV7RxCocoa15ControlPropertyq__GC7RxSwift8Variableq___PS2_10Disposable_U_FQ_T_ + 91
    28  TestRX                              0x000000010c6fcc58 _TTRGrXFo_iq__dT__XFo_iq__iT__ + 24
    29  TestRX                              0x000000010c6fc8b1 _TPA__TTRGrXFo_iq__dT__XFo_iq__iT__ + 97
    30  RxSwift                             0x000000010c991ec4 _TFFeRq_7RxSwift14ObservableType_S_S0_9subscribeuRq_S0__Fq_FT6onNextGSqFqq_S0_1ET__7onErrorGSqFPSs9ErrorType_T__11onCompletedGSqFT_T__10onDisposedGSqFT_T___PS_10Disposable_U_FGOS_5EventQQPS0_1E_T_ + 772
    31  RxSwift                             0x000000010c9911ec _TPA__TFFeRq_7RxSwift14ObservableType_S_S0_9subscribeuRq_S0__Fq_FT6onNextGSqFqq_S0_1ET__7onErrorGSqFPSs9ErrorType_T__11onCompletedGSqFT_T__10onDisposedGSqFT_T___PS_10Disposable_U_FGOS_5EventQQPS0_1E_T_ + 284
    32  RxSwift                             0x000000010c8fb368 _TFC7RxSwift17AnonymousObserver6onCoreurfGS0_q__FGOS_5Eventq__T_ + 392
    33  RxSwift                             0x000000010c9a03ae _TFC7RxSwift12ObserverBase2onurfGS0_q__FGOS_5Eventq__T_ + 974
    34  RxSwift                             0x000000010c9a094f _TTWurGC7RxSwift12ObserverBaseq__S_12ObserverTypeS_FS1_2onuRq_S1__fq_FGOS_5Eventqq_S1_1E_T_ + 63
    35  RxSwift                             0x000000010c9e2121 _TFC7RxSwift4Sink9forwardOnuRq_S_12ObserverType_fGS0_q__FGOS_5Eventqq_S1_1E_T_ + 625
    36  RxSwift                             0x000000010c9ed4af _TFC7RxSwift15SubscribeOnSink2onu0_Rq_S_14ObservableTypeq0_S_12ObserverTypezqq_S1_1Eqq0_S2_1E_fGS0_q_q0__FGOS_5Eventqq_S1_1E_T_ + 463
    37  RxSwift                             0x000000010c9ede13 _TTWu0_Rq_7RxSwift14ObservableTypeq0_S_12ObserverTypezqq_S0_1Eqq0_S1_1E_GCS_15SubscribeOnSinkq_q0__S1_S_FS1_2onuRq_S1__fq_FGOS_5Eventqq_S1_1E_T_ + 83
    38  RxSwift                             0x000000010c9e2121 _TFC7RxSwift4Sink9forwardOnuRq_S_12ObserverType_fGS0_q__FGOS_5Eventqq_S1_1E_T_ + 625
    39  RxSwift                             0x000000010c9684bf _TFC7RxSwift12DeferredSink2onu0_Rq_S_14ObservableTypeq0_S_12ObserverTypezqq_S1_1Eqq0_S2_1E_fGS0_q_q0__FGOS_5Eventqq_S1_1E_T_ + 463
    40  RxSwift                             0x000000010c9688c3 _TTWu0_Rq_7RxSwift14ObservableTypeq0_S_12ObserverTypezqq_S0_1Eqq0_S1_1E_GCS_12DeferredSinkq_q0__S1_S_FS1_2onuRq_S1__fq_FGOS_5Eventqq_S1_1E_T_ + 83
    41  RxSwift                             0x000000010c9e2121 _TFC7RxSwift4Sink9forwardOnuRq_S_12ObserverType_fGS0_q__FGOS_5Eventqq_S1_1E_T_ + 625
    42  RxSwift                             0x000000010c96c286 _TFC7RxSwift24DistinctUntilChangedSink2onu0_Rq_S_12ObserverType_fGS0_q_q0__FGOS_5Eventqq_S1_1E_T_ + 2326
    43  RxSwift                             0x000000010c96cdc3 _TTWu0_Rq_7RxSwift12ObserverType_GCS_24DistinctUntilChangedSinkq_q0__S0_S_FS0_2onuRq_S0__fq_FGOS_5Eventqq_S0_1E_T_ + 83
    44  RxSwift                             0x000000010c9e2121 _TFC7RxSwift4Sink9forwardOnuRq_S_12ObserverType_fGS0_q__FGOS_5Eventqq_S1_1E_T_ + 625
    45  RxSwift                             0x000000010c97ee49 _TFC7RxSwift7MapSink2onu0_Rq0_S_12ObserverType_fGS0_q_q0__FGOS_5Eventq__T_ + 985
    46  RxSwift                             0x000000010c97f423 _TTWu0_Rq0_7RxSwift12ObserverType_GCS_7MapSinkq_q0__S0_S_FS0_2onuRq_S0__fq_FGOS_5Eventqq_S0_1E_T_ + 83
    47  RxSwift                             0x000000010c8fbd31 _TPA + 113
    48  RxSwift                             0x000000010c8fb933 _TFV7RxSwift11AnyObserver2onurfGS0_q__FGOS_5Eventq__T_ + 387
    49  RxSwift                             0x000000010c8fba44 _TTWurGV7RxSwift11AnyObserverq__S_12ObserverTypeS_FS1_2onuRq_S1__fq_FGOS_5Eventqq_S1_1E_T_ + 68
    50  RxSwift                             0x000000010c903e35 _TFeRq_7RxSwift12ObserverType_S_VS_3Bag2onuRq_S0__fGS1_q__FGOS_5Eventqq_S0_1E_T_ + 1141
    51  RxSwift                             0x000000010c9a4df0 _TFC7RxSwift14PublishSubject16_synchronized_onurfGS0_q__FGOS_5Eventq__T_ + 1744
    52  RxSwift                             0x000000010c9a4689 _TFC7RxSwift14PublishSubject2onurfGS0_q__FGOS_5Eventq__T_ + 425
    53  RxCocoa                             0x000000010c7af712 _TFC7RxCocoa13DelegateProxy19interceptedSelectorfS0_FTV10ObjectiveC8Selector13withArgumentsGSQGSaPSs9AnyObject____T_ + 530
    54  RxCocoa                             0x000000010c7af7cd _TToFC7RxCocoa13DelegateProxy19interceptedSelectorfS0_FTV10ObjectiveC8Selector13withArgumentsGSQGSaPSs9AnyObject____T_ + 125
    55  RxCocoa                             0x000000010c78ede4 -[_RXDelegateProxy forwardInvocation:] + 180
    56  CoreFoundation                      0x000000010ccba727 ___forwarding___ + 487
    57  CoreFoundation                      0x000000010ccba4b8 _CF_forwarding_prep_0 + 120
    58  UIFoundation                        0x00000001144aa4ef -[NSTextStorage processEditing] + 283
    59  UIFoundation                        0x00000001144aa18b -[NSTextStorage endEditing] + 82
    60  UIKit                               0x000000010df740fd -[UITextInputController _insertText:fromKeyboard:] + 505
    61  UIKit                               0x000000010df74bcd -[UITextInputController insertText:] + 365
    62  UIKit                               0x000000010df2778b -[UITextView insertText:] + 62
    63  UIKit                               0x000000010d829a9b -[UIKeyboardImpl insertText:] + 149
    64  UIKit                               0x000000010d826278 -[UIKeyboardImpl performKeyboardOutput:] + 496
    65  UIKit                               0x000000010d825e65 __55-[UIKeyboardImpl handleKeyboardInput:executionContext:]_block_invoke_2 + 164
    66  UIKit                               0x000000010df94724 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 332
    67  Foundation                          0x000000010d149067 __NSThreadPerformPerform + 283
    68  CoreFoundation                      0x000000010cc90a31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    69  CoreFoundation                      0x000000010cc8695c __CFRunLoopDoSources0 + 556
    70  CoreFoundation                      0x000000010cc85e13 __CFRunLoopRun + 867
    71  CoreFoundation                      0x000000010cc85828 CFRunLoopRunSpecific + 488
    72  GraphicsServices                    0x0000000113e90ad2 GSEventRunModal + 161
    73  UIKit                               0x000000010d581610 UIApplicationMain + 171
    74  TestRX                              0x000000010c6fd47d main + 109
    75  libdyld.dylib                       0x00000001105bd92d start + 1
    76  ???                                 0x0000000000000001 0x0 + 1
)

我能够在2.1.02.2.0上重现这一点

有人对如何解决这个问题有任何想法吗?

我目前的解决方法是执行单向绑定并将文本视图初始化为初始属性。

    textview.text = testVar.value
    textview.rx_text.subscribeNext({ self.testVar.value = $0 }) // and dispose it

这不允许我对任何模型更改做出反应,但就我而言,我很确定没有用户输入,模型不会更改。

从 Rx 2.2.0 支持,工作正常

https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Operators.swift

最新更新