├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── issue-template.md ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Documents ├── Chinese │ ├── BasicOperators.md │ ├── CONTRIBUTING_Chinese.md │ ├── FrameworkOverview.md │ └── MemoryManagement.md ├── English │ ├── BasicOperators.md │ ├── CONTRIBUTING.md │ ├── FrameworkOverview.md │ └── MemoryManagement.md └── common │ ├── Copyright.txt │ └── commentformat.txt ├── EasyReact.podspec ├── EasyReact ├── Assets │ └── .gitkeep ├── Classes │ ├── Categories │ │ ├── NSObject+EZR_Extension.h │ │ └── NSObject+EZR_Extension.m │ ├── Core │ │ ├── EZRBlockCancelable.h │ │ ├── EZRBlockCancelable.m │ │ ├── EZRCancelable.h │ │ ├── EZRCancelableBag.h │ │ ├── EZRCancelableBag.m │ │ ├── EZRCancelableBagProtocol.h │ │ ├── EZREdge.h │ │ ├── EZREmpty.h │ │ ├── EZREmpty.m │ │ ├── EZRListen.h │ │ ├── EZRListen.m │ │ ├── EZRListenContext.h │ │ ├── EZRListenContext.m │ │ ├── EZRListenEdge.h │ │ ├── EZRMetaMacros.h │ │ ├── EZRMutableNode.h │ │ ├── EZRMutableNode.m │ │ ├── EZRNextReceiver.h │ │ ├── EZRNode+Graph.h │ │ ├── EZRNode+Graph.m │ │ ├── EZRNode+Listen.h │ │ ├── EZRNode+Listen.m │ │ ├── EZRNode+Mutable.h │ │ ├── EZRNode+Mutable.m │ │ ├── EZRNode+Operation.h │ │ ├── EZRNode+Operation.m │ │ ├── EZRNode+Traversal.h │ │ ├── EZRNode+Traversal.m │ │ ├── EZRNode+Value.h │ │ ├── EZRNode+Value.m │ │ ├── EZRNode.h │ │ ├── EZRNode.m │ │ ├── EZRTransform.h │ │ ├── EZRTransform.m │ │ ├── EZRTransformEdge.h │ │ ├── EZRTypeDefine.h │ │ ├── ListenEdges │ │ │ ├── EZRBlockListen.h │ │ │ ├── EZRBlockListen.m │ │ │ ├── EZRDeliveredListen.h │ │ │ └── EZRDeliveredListen.m │ │ ├── NSObject+EZR_Listen.h │ │ ├── NSObject+EZR_Listen.m │ │ ├── NodeTransforms │ │ │ ├── EZRCaseTransform.h │ │ │ ├── EZRCaseTransform.m │ │ │ ├── EZRCombineTransform.h │ │ │ ├── EZRCombineTransform.m │ │ │ ├── EZRCombineTransformGroup.h │ │ │ ├── EZRCombineTransformGroup.m │ │ │ ├── EZRDelayTransform.h │ │ │ ├── EZRDelayTransform.m │ │ │ ├── EZRDeliverTransform.h │ │ │ ├── EZRDeliverTransform.m │ │ │ ├── EZRDistinctTransform.h │ │ │ ├── EZRDistinctTransform.m │ │ │ ├── EZRFilteredTransform.h │ │ │ ├── EZRFilteredTransform.m │ │ │ ├── EZRFlattenTransform.h │ │ │ ├── EZRFlattenTransform.m │ │ │ ├── EZRMapTransform.h │ │ │ ├── EZRMapTransform.m │ │ │ ├── EZRScanTransform.h │ │ │ ├── EZRScanTransform.m │ │ │ ├── EZRSkipTransform.h │ │ │ ├── EZRSkipTransform.m │ │ │ ├── EZRSwitchMapTransform.h │ │ │ ├── EZRSwitchMapTransform.m │ │ │ ├── EZRTakeTransform.h │ │ │ ├── EZRTakeTransform.m │ │ │ ├── EZRThrottleTransform.h │ │ │ ├── EZRThrottleTransform.m │ │ │ ├── EZRZipTransform.h │ │ │ ├── EZRZipTransform.m │ │ │ ├── EZRZipTransformGroup.h │ │ │ └── EZRZipTransformGroup.m │ │ └── Private │ │ │ ├── EZRListenContext+ProjectPrivate.h │ │ │ ├── EZRMetaMacrosPrivate.h │ │ │ ├── EZRMutableNode+ProjectPrivate.h │ │ │ ├── EZRNode+MapEach.h │ │ │ ├── EZRNode+MapEach.m │ │ │ └── EZRNode+ProjectPrivate.h │ ├── EasyReact.h │ └── Utils │ │ ├── EZRPathTrampoline.h │ │ ├── EZRPathTrampoline.m │ │ ├── EZRSenderList.h │ │ └── EZRSenderList.m └── EasyReact.modulemap ├── Example ├── Benchmark │ ├── Benchmark.h │ ├── Benchmark.m │ ├── BenchmarkResultProtocol.h │ ├── BenchmarkTargetProtocol.h │ ├── BenchmarkTest.h │ ├── BenchmarkTest.m │ ├── BenchmarkTestMethod.h │ ├── Result │ │ ├── BenchmarkResult.h │ │ └── BenchmarkResult.m │ ├── SupportFiles │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Benchmark-Bridging-Header.h │ │ ├── Info.plist │ │ └── main.m │ ├── Target │ │ ├── EZRBenchmarkTarget.h │ │ ├── EZRBenchmarkTarget.m │ │ ├── RACBenchmarkTarget.h │ │ ├── RACBenchmarkTarget.m │ │ └── RXSwiftBenchmarkTarget.swift │ ├── TestMethod │ │ ├── BenchmarkCPUTestMethod.h │ │ └── BenchmarkCPUTestMethod.m │ ├── TestObject.h │ ├── TestObject.m │ ├── ViewController.h │ └── ViewController.m ├── EasyReact.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ ├── EasyReact-Example-Debug.xcscheme │ │ └── EasyReact-Example-Release.xcscheme ├── EasyReact.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist ├── EasyReact │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ERAppDelegate.h │ ├── ERAppDelegate.m │ ├── ERViewController.h │ ├── ERViewController.m │ ├── EasyReact-Info.plist │ ├── EasyReact-Prefix.pch │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m ├── Podfile ├── Podfile.lock └── Tests │ ├── EZRListenContext.m │ ├── EZRMutableNodeSpec.m │ ├── EZRNode+Graph.m │ ├── EZRNode+Operation.m │ ├── EZRNode+Value.m │ ├── EZRNodeSpec.m │ ├── EZRTransformSpec.m │ ├── EasyReact_Example-Bridging-Header.h │ ├── NSObject+ER_Extension.m │ ├── TestSupportClasses │ ├── Matchers │ │ ├── AssertionHandler.h │ │ ├── AssertionHandler.m │ │ ├── CustomMatchers.h │ │ ├── CustomMatchers.m │ │ ├── beEmptyValue.swift │ │ ├── beReleasedCorrectly.swift │ │ ├── hasAssert.swift │ │ ├── matchGraph.swift │ │ └── receive.swift │ ├── SwiftSpec.swift │ ├── TestKVOClass.h │ └── TestKVOClass.m │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ └── en.lproj │ └── InfoPlist.strings ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README-Chinese.md ├── README.md ├── _Pods.xcodeproj ├── codecov.yml ├── fastlane ├── Appfile ├── Fastfile ├── README.md └── actions │ └── codecov.rb └── images ├── Banner.png └── benchmark.png /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue template 3 | about: Describe this issue template's purpose here. 4 | 5 | --- 6 | 7 | 10 | 11 | ### Context and Description 12 | 13 | 14 | 15 | ### Environment Details 16 | 17 | * EasyReact version: 18 | * iOS version: 19 | * Xcode version: 20 | * Other informations: 21 | 22 | ### Expected behavior 23 | 24 | 25 | 26 | ### Actual behavior 27 | 28 | 29 | 30 | ### Steps to Reproduce 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | # 33 | Example/Pods/ 34 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode9 6 | language: objective-c 7 | cache: 8 | - bundler 9 | - cocoapods 10 | before_install: 11 | - bundle install 12 | script: 13 | - fastlane test_and_report 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## 2.2.0 - 2018-07-07 11 | 12 | ### Added 13 | 14 | - Add documents for english language. 15 | 16 | ### Changed 17 | 18 | - Change Dependency to EasyFoundation. 19 | 20 | ### Fixed 21 | 22 | - Optimize performance. 23 | 24 | ## 2.1.0 25 | 26 | - Fixed internal memory leak in EZR_PATH 27 | - Rename the EZRNodeTransform Series to Edge 28 | - Added - [EZRNode combine:], - [EZRNode merge:], - [EZRNode zip:] API 29 | - Added - [EZRNode switch:], - [EZRNode switchMap:], - [EZRNode if:], - [EZRNode else:], - [EZRNode case:] API 30 | - Fixed issue that skip take flattenMap operation reuse Transform old data 31 | - Updated EasyTuple 1.10 and EasySequence 1.2.1 32 | 33 | ## 2.0.0 34 | 35 | - Use EasySequence instead of System Container 36 | - Fixed a bug could cause the listening fail by the hash conflict 37 | - Rename prefix ER to EZR 38 | - Implement NSObject `ezr_toNode` and ʻezr_toMutableNode` 39 | - Added `getValue` `valueWith:` method in EZRNode + Value Category 40 | - Implement the EZRNode `scan:reduce:` method 41 | - Modified EZRNode as immutable object, EZRMutableNode as mutable object 42 | - Reconstructed the graph theory memory management logic 43 | - Changed the Listen interface 44 | - Changed Ztuple dependency to EasyTuple 45 | - Take out Utils related class, it would migrate to EasySequence in the future 46 | - Add documents 47 | 48 | ## 1.3.2 49 | 50 | - Modified Node memory leak problem 51 | - Modified DelivedOnMainQueue implementation 52 | 53 | ## 1.3.1 54 | 55 | - Added `er_deallocCancelBag` interface 56 | - Modified the implementation of `er_listenDealloc` 57 | 58 | ## 1.3.0 59 | 60 | - Added `delay` `then` `select:` interface 61 | - Rename throttle to throttleOnMainQueue 62 | 63 | ## 1.2.2 64 | 65 | - Added `clean` interface 66 | 67 | ## 1.2.1 68 | 69 | - Added `fork` interface 70 | 71 | ## 1.2.0 72 | 73 | - Added `deliverOn:(dispatch_queue_t)queue` and `deliverOnMainQueue;` interfaces 74 | 75 | ## 1.1.0 76 | 77 | - Rename syncTo to SyncWith 78 | 79 | ## 1.0.0 80 | 81 | - First Version 82 | -------------------------------------------------------------------------------- /Documents/Chinese/CONTRIBUTING_Chinese.md: -------------------------------------------------------------------------------- 1 | # 为 EasyReact 贡献代码 2 | 3 | 我们鼓励使用者向 EasyReact 项目做贡献,共享代码的规则可以参考下面的条例。 4 | 5 | 如果你碰见了一些不明白的问题 或者是需要和开发组人员交流,可以通过 [EasyReact Team](mailto:it_easyreact@meituan.com) 邮箱联系我们。 6 | 7 | ## 目录 8 | 9 | 10 | 11 | - [为 EasyReact 贡献代码](#为-easyreact-贡献代码) 12 | - [快速入手](#快速入手) 13 | - [创建 Pull Requests](#创建-pull-requests) 14 | - [提问](#提问) 15 | - [报告 Issues](#报告-issues) 16 | - [参考信息](#参考信息) 17 | 18 | 19 | 20 | ## 快速入手 21 | 22 | 23 | 为了给 EasyReact 贡献代码,你应该打开一个终端 24 | 25 | 1. 首先再 fork 本项目 然后 clone 到本地的工作目录。 26 | 27 | `$ git clone https://github.com/YOUR_GITHUB_ID/EasyReact` 28 | 29 | 30 | 2. 通常一次 Pull Request 是为了解决一个 ISSUE, 已有的 ISSUE 列表可以在这里找到[ISSUE](https://github.com/meituan/EasyReact/issues)。 31 | 32 | 如果没有相关联的 ISSUE, 可以向开发组的人员发邮件[EasyReact Team](mailto:it_easyreact@meituan.com),我们将会与你讨论这次贡献。 33 | 34 | 3. EasyReact 项目使用 Apache License 2.0 协议发布. 因此每个文件头部信息必须带上相关协议版权信息。对于一个新文件可以通过一下链接 [License](../common/Copyright.txt) 找到这个模板,将其复制在新文件的顶部即可。 35 | 36 | 4. 创建新的 PR 前应该保证所有的测试用例是通过的,并且测试用例的覆盖度要大于之前的。如果你对项目添加了新的功能,相应的也需要补充对于的测试用例。 37 | 如果你对书写测试用例有疑问, 可以通过邮件与开发人员联系[EasyReact Team](mailto:it_easyreact@meituan.com)。 38 | 39 | 5. Git 想要的提交信息要遵守如下模板[commit message templates](../common/commentformat.txt)。 40 | 41 | 6. 如果以上步骤都满足,可以创建你的 PR 了。 42 | 43 | 44 | ## 创建 Pull Requests 45 | 46 | **注意:** 创建 PR 前一定要确保所有的测试用例通过。 47 | 48 | EasyReact 使用 [持续集成](https://en.wikipedia.org/wiki/Continuous_integration). 因此你可能在你的 PR 中看到 [Travis CI](https://travis-ci.com/) 相关的评论. Travis is 是一个外部工具,我们使用这个工具检查每个 PR 然后测试对应的测试用例,如果测试用例失败了 这个 PR 不能合入到 master 分支。使用 Travis CI 工具可以确保每次提交代码的稳定性。 49 | 50 | 当你创建一个PR时,请检查如下要求 51 | 52 | 1. 请在本地做相关的 diff 确保无关的代码风格没有发生改变,如果你认为代码风格有问题,创建一个单独的 PR 来修改这个问题。 53 | 2. 提交代码前使用 `git diff --check` 命令检查下是否有多余的空白字符和换行。 54 | 55 | ## 提问 56 | 57 | 如果你又其他访问的疑惑或者需要和开发人员沟通, 可以给我们发邮件 [EasyReact Team](mailto:it_easyreact@meituan.com).。 58 | 59 | ## 报告 Issues 60 | 61 | 如果有 ISSUE 需要提出,请遵守此 [模板](../../.github/ISSUE_TEMPLATE/issue-template.md)。 62 | 63 | --- 64 | 65 | ### 参考信息 66 | 67 | * [GitHub 帮助页面](https://help.github.com) 68 | * [如何创建一个拉取请求](https://help.github.com/articles/creating-a-pull-request/) -------------------------------------------------------------------------------- /Documents/common/Copyright.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Beijing Sankuai Online Technology Co.,Ltd (Meituan) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | **/ -------------------------------------------------------------------------------- /Documents/common/commentformat.txt: -------------------------------------------------------------------------------- 1 | () : 2 | 3 | 4 | 5 | 6 |