duan.ca
域名年龄: 11年9个月17天HTTP/1.1 301 永久重定向 访问时间:2019年09月07日 17:52:27 Transfer-Encoding: chunked 连接:keep-alive 缓存控制:max-age=3600 过期时间:2019年09月07日 18:52:27 目标网址:https://duan.ca/ X-Content-Type-Options: nosniff 动作:Accept-Encoding 服务器:cloudflare CF-RAY: 5127ca38ebe969a4-CDG HTTP/1.1 200 OK 访问时间:2019年09月07日 17:52:27 类型:text/html; charset=utf-8 Transfer-Encoding: chunked 连接:keep-alive 设置Cookie:__cfduid=d47a86135eb11d6926167bcf0893534421567849947; expires=Sun, 06-Sep-20 09:52:27 GMT; path=/; domain=.duan.ca; HttpOnly; Secure 修改日期:2019年07月03日 00:30:04 动作:Accept-Encoding Access-Control-Allow-Origin: * 过期时间:2019年09月07日 18:52:27 缓存控制:max-age=600 X-Proxy-Cache: MISS X-GitHub-Request-Id: A1FA:347A:751DB:9CFAE:5D737DDB Strict-Transport-Security: max-age=15552000; includeSubDomains; preload X-Content-Type-Options: nosniff Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" 服务器:cloudflare CF-RAY: 5127ca39589dcd83-CDG Content-Encoding: gzip 网站编码:utf-8
Daniel Duan's blogarticlesvideosLinksProjectsAboutOn the Subject of Interface Hygiene01 Jul 2019|Combine,SwiftIn a purly reactive world, your entire program merge into a single stream. Now,close your eyes, and envision: your project as one, beautiful, stream.Now open your eyes. Yeah, it’s not. Your project is a Mac or iOS app. It’s fullof your memories, sweat, and blood. And you are ready to sweat and bleed somemore by putting some Combine and SwiftUI into it. You watched the WWDC19sessions and learned that “Subjcets are super powerful”. You looked into yourcode and realized you can’t really do anything with Combine without Subjectsat the current state of the project.Well…Here are a few habits that help keeping your project that prevasively usesCombine.Subject sane. They should seem obvious to anyone who understandsMurphy’s law and the value of minialism in interfaces. If you already are usingsome reactive stream implementation, substitute the types with theircounterparts in your framework and these rules should seem down right basic.Vend Subjects as PublishersSubjects help bridge from the imperitive to the reactive world. Somewhatparadoxically, sharing them is not very “RX-y”. This is akin to prefering letsover var.Most of the time, what you want to share is the values pumped into the stream,not the privilage to mutate it. Because Subjects conform to Publisher, it’seasy to hide from the users the fact that your stream is backed by them.// Bad: now anyone who get a hold of it can mess with your stream!public enum GreatInts {public var updates = CurrentValueSubject<Int, Never>(0)}With Combine this conversion happens via type-erasure:// Better: all your users care is the stream (publisher), so give them that!public enum GreatInts {// Internally, it's backed by a subject.var subject = CurrentValueSubject<Int, Never>(0)// Externally, it's just a Publisher. public var subject: AnyPublisher<Int, Never> {subject.eraseToAnyPublisher()}}CurrentValueSubject natually caches the latest valueRX theorists will hate this: sometimes it’s just practical to exposea synchronous interface to the latest vaule in the stream!Two things.It might be tempting to expose the subject and let your user use its.value. Well, you shouldn’t (as explained in the previous section).A separate interface dedicated to the latest value prevents people frompolluting your stream.// (Still) badpublic final class GreatInts {public var updates = CurrentValueSubject<Int, Never>(0)}Remember CurrentValueSubject has that .value property! It may seemsurprising, but I’ve seen folks transitioning to RX clinging to the old ways:public final class GreatInts {// well, at least it's not a public subject...var subject = CurrentValueSubject<Int, Never>(0) // <- initial value 0public var updates: AnyPublisher<Int, Never> {subject.eraseToAnyPublisher()}// Wait, there's that 0 againpublic var latest: Int = 0 {didSet {subject.send(latest) // ?}}}First, you’ll notice
© 2010 - 2020 网站综合信息查询 同IP网站查询 相关类似网站查询 网站备案查询网站地图 最新查询 最近更新 优秀网站 热门网站 全部网站 同IP查询 备案查询
2025-08-07 14:08, Process in 0.0465 second.