Skip to content

Commit 07af30d

Browse files
authored
Merge pull request #62 from GeekTree0101/feature/VEditorKit-Improvement-safe-and-performance
improve unused _ASTableCellView manage safe and performance
2 parents 6af7bb1 + 9391ffe commit 07af30d

2 files changed

Lines changed: 42 additions & 35 deletions

File tree

Example/VEditorKit/Controllers/EditorNodeController.swift

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -221,25 +221,17 @@ extension EditorNodeController {
221221
}
222222

223223
@objc func pushXMLViewer() {
224-
self.node.synchronizeFetchContents { [weak self] () in
225-
226-
guard let output = self?.node.buildXML(packageTag: "content") else {
227-
return
228-
}
229-
let vc = XMLViewController.init(output)
230-
self?.navigationController?.pushViewController(vc, animated: true)
231-
}
224+
self.node.synchronizeFetchContents()
225+
guard let output = self.node.buildXML(packageTag: "content") else { return }
226+
let vc = XMLViewController.init(output)
227+
self.navigationController?.pushViewController(vc, animated: true)
232228
}
233229

234230
@objc func previewViewer() {
235-
self.node.synchronizeFetchContents { [weak self] () in
236-
guard let xmlString = self?.node
237-
.buildXML(packageTag: "content") else {
238-
return
239-
}
240-
let vc = EditorNodeController(isEditMode: false, xmlString: xmlString)
241-
self?.navigationController?.pushViewController(vc, animated: true)
242-
}
231+
self.node.synchronizeFetchContents()
232+
let xmlString = self.node.buildXML(packageTag: "content")
233+
let vc = EditorNodeController(isEditMode: false, xmlString: xmlString)
234+
self.navigationController?.pushViewController(vc, animated: true)
243235
}
244236
}
245237

VEditorKit/Classes/VEditorNode.swift

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
6969
}
7070
}
7171

72-
open var activeTextContainCellNode: VEditorTextCellNode? {
72+
open weak var activeTextContainCellNode: VEditorTextCellNode? {
7373
didSet {
7474
self.observeActiveTextNode()
7575
}
@@ -93,6 +93,7 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
9393

9494
private var typingControls: [VEditorTypingControlNode] = []
9595
private var activeTextDisposeBag = DisposeBag()
96+
private let synchronizeContentLock = NSLock()
9697

9798
public init(editorRule: VEditorRule,
9899
controlAreaNode: ASDisplayNode?) {
@@ -194,7 +195,6 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
194195
.disposed(by: cellNode.disposeBag)
195196

196197
cellNode.rx.failed
197-
.observeOn(MainScheduler.instance)
198198
.bind(to: self.rx.deleteContent(animated: true))
199199
.disposed(by: cellNode.disposeBag)
200200

@@ -235,6 +235,27 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
235235
}
236236
}
237237

238+
private func removeUnusedInternalASTableCellViewIfNeeds() {
239+
// Bug Issue: https://github.com/TextureGroup/Texture/issues/1407
240+
let currentActiveTextASCellView = self.activeTextContainCellNode?.view.superview?.superview
241+
242+
let invalidSubViews = self.tableNode.view.subviews
243+
.filter({ subView -> Bool in
244+
return !self.tableNode.view.visibleCells.map({ $0.frame }).contains(subView.frame)
245+
})
246+
.filter({ $0 != currentActiveTextASCellView })
247+
248+
guard !invalidSubViews.filter({ $0 != currentActiveTextASCellView }).isEmpty else { return }
249+
250+
for view in invalidSubViews {
251+
view.removeFromSuperview()
252+
}
253+
}
254+
255+
open func scrollViewDidScroll(_ scrollView: UIScrollView) {
256+
self.removeUnusedInternalASTableCellViewIfNeeds()
257+
}
258+
238259
/**
239260
Register Typing Control Nodes
240261

@@ -531,8 +552,10 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
531552
- section: editor target section
532553
- complate: complate syncronize callback
533554
*/
534-
open func synchronizeFetchContents(in section: Int = 0,
535-
_ complate: @escaping () -> Void) {
555+
open func synchronizeFetchContents(in section: Int = 0) {
556+
defer { self.synchronizeContentLock.unlock() }
557+
self.synchronizeContentLock.lock()
558+
536559
let numberOfSection = self.tableNode.numberOfSections
537560
guard section >= 0, section < numberOfSection else {
538561
fatalError("Invalid access section \(section) in \(numberOfSection)")
@@ -552,8 +575,6 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
552575
.attributedString() else { return }
553576
self.editorContents[index] = currentAttributedText
554577
}
555-
556-
complate()
557578
}
558579

559580
/**
@@ -617,21 +638,10 @@ open class VEditorNode: ASDisplayNode, ASTableDelegate, ASTableDataSource {
617638
self.editorContents.remove(at: indexPath.row)
618639
}
619640

620-
for deleteIndexPath in deleteIndexPaths {
621-
self.tableNode.view.cellForRow(at: deleteIndexPath)?.removeFromSuperview()
622-
}
623-
624641
self.tableNode.performBatchUpdates({
625642
self.tableNode.deleteRows(at: deleteIndexPaths,
626643
with: animated ? .automatic: .none)
627-
}, completion: { _ in
628-
// Texture Bug Issue, ref: https://github.com/TextureGroup/Texture/issues/1407
629-
_ = self.tableNode.view.subviews
630-
.filter({ $0 is UITableViewCell })
631-
.filter { $0.subviews.first?.subviews.isEmpty ?? false ||
632-
$0.subviews.first?.subviews.first is UIImageView }
633-
.map { $0.removeFromSuperview() }
634-
})
644+
}, completion: nil)
635645
}
636646

637647
/**
@@ -875,7 +885,12 @@ extension VEditorNode {
875885
switch scope {
876886
case .automatic:
877887
if let activeTextNode = self.activeTextNode {
878-
return .splitIndex(activeTextNode.selectedRange.location)
888+
if activeTextNode.selectedRange.location == 0,
889+
let indexPath = activeTextContainCellNode?.indexPath {
890+
return .indexPath(indexPath)
891+
} else {
892+
return .splitIndex(activeTextNode.selectedRange.location)
893+
}
879894
} else {
880895
let lastIndex: Int = max(0, self.editorContents.count)
881896
return .indexPath(.init(row: lastIndex, section: section))

0 commit comments

Comments
 (0)