- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
例如,考虑一下:
public IDisposable Subscribe<T>(IObserver<T> observer)
{
return eventStream.Where(e => e is T).Cast<T>().Subscribe(observer);
}
eventStream
是长期存在的事件源。短暂的客户端将使用此方法订阅一段时间,然后通过调用 Dispose
取消订阅。在返回IDisposable
.
但是,虽然 eventStream
仍然存在,应该保留在内存中,有 2 个新的 IObservables
通过此方法创建 - Where()
返回的那个eventStream
可能保存在内存中的方法,以及由 Cast<T>()
返回的那个Where()
返回的方法可能保存在内存中方法。
如何清理这些“中间 IObservables”(是否有更好的名称?)?或者它们现在会在 eventStream
的生命周期内存在吗?即使他们不再有订阅并且除了他们的来源之外没有其他人引用他们 IObservable
因此永远不会再有订阅?
如果他们通过通知他们的 parent 他们不再有订阅而被清理,他们怎么知道没有其他人引用他们并且可能在以后的某个时候订阅他们?
最佳答案
However, while the eventStream still exists and should be kept in memory, there has been 2 new IObservables created by this method - the one returned by the Where() method that is presumably held in memory by the eventStream, and the one returned by the Cast() method that is presumably held in memory by the one returned by the Where() method.
你有这个落后。让我们来看看正在发生的事情的链条。
IObservable<T> eventStream; //you have this defined and assigned somewhere
public IDisposable Subscribe<T>(IObserver<T> observer)
{
//let's break this method into multiple lines
IObservable<T> whereObs = eventStream.Where(e => e is T);
//whereObs now has a reference to eventStream (and thus will keep it alive),
//but eventStream knows nothing of whereObs (thus whereObs will not be kept alive by eventStream)
IObservable<T> castObs = whereObs.Cast<T>();
//as with whereObs, castObs has a reference to whereObs,
//but no one has a reference to castObs
IDisposable ret = castObs.Subscribe(observer);
//here is where it gets tricky.
return ret;
}
ret
引用或不引用的内容取决于各种可观察对象的实现。从我在 Rx 库的 Reflector 中看到的和我自己编写的运算符来看,大多数运算符不会返回引用了运算符可观察对象本身的一次性对象。
例如,Where
的基本实现类似于(直接在编辑器中键入,无错误处理)
IObservable<T> Where<T>(this IObservable<T> source, Func<T, bool> filter)
{
return Observable.Create<T>(obs =>
{
return source.Subscribe(v => if (filter(v)) obs.OnNext(v),
obs.OnError, obs.OnCompleted);
}
}
请注意,返回的一次性对象将通过创建的观察者引用过滤器函数,但不会引用 Where
可观察对象。 Cast
可以使用相同的模式轻松实现。本质上,运营商成为观察者包装工厂。
所有这一切对手头问题的暗示是,中间 IObservables 有资格在方法结束时 进行垃圾回收。传递给 Where
的过滤器函数会在订阅结束时一直存在,但是一旦订阅被处理或完成,只有 eventStream
会保留(假设它仍然存在)。
编辑 对于 supercat 的评论,让我们看看编译器如何重写它或者你将如何在没有闭包的情况下实现它。
class WhereObserver<T> : IObserver<T>
{
WhereObserver<T>(IObserver<T> base, Func<T, bool> filter)
{
_base = base;
_filter = filter;
}
IObserver<T> _base;
Func<T, bool> _filter;
void OnNext(T value)
{
if (filter(value)) _base.OnNext(value);
}
void OnError(Exception ex) { _base.OnError(ex); }
void OnCompleted() { _base.OnCompleted(); }
}
class WhereObservable<T> : IObservable<T>
{
WhereObservable<T>(IObservable<T> source, Func<T, bool> filter)
{
_source = source;
_filter = filter;
}
IObservable<T> source;
Func<T, bool> filter;
IDisposable Subscribe(IObserver<T> observer)
{
return source.Subscribe(new WhereObserver<T>(observer, filter));
}
}
static IObservable<T> Where(this IObservable<T> source, Func<T, bool> filter)
{
return new WhereObservable(source, filter);
}
您可以看到观察者不需要对生成它的可观察对象的任何引用,并且可观察对象也不需要跟踪它创建的观察者。我们甚至没有创建任何新的 IDisposable 来从我们的订阅中返回。
实际上,Rx 有一些用于匿名可观察对象/观察者的实际类,它们接受委托(delegate)并将接口(interface)调用转发给这些委托(delegate)。它使用闭包来创建这些委托(delegate)。编译器不需要发出实际实现接口(interface)的类,但翻译的精神保持不变。
关于c# - 没有最终订阅者的 'Intermediate IObservables' 在根 IObservable 的生命周期内保留在内存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9737711/
考虑需要与 iOS 5 和 iOS 6 兼容的应用。 有没有办法标记纯粹为了 iOS 5 兼容性而存在的代码,以便当部署目标最终更改为 iOS 6 时它显示为编译错误(或警告)? 像这样: #IF_D
我想我知道答案但是...有什么方法可以防止全局变量被稍后执行的 修改吗? ?我知道全局变量首先是不好的,但在必要时,有没有办法让它成为“最终”或“不可变”?欢迎黑客/创造性的解决方案。谢谢 最佳答案
class Foo { final val pi = 3 } 是否每Foo对象有一个 pi成员?因此我应该把 pi在伴生对象中? 最佳答案 如果您担心内存占用,您可以考虑将此字段移动到伴随对象中。
随着可用的 Web 开发框架种类繁多,似乎总是有一种“尝试新事物”的永久动机。因此,我们中的一些人发现自己用一个框架换另一个框架,从来没有对最终结果完全满意。当然,总会有一个特定的 Web 框架可以完
在MDN中指出, If the finally block returns a value, this value becomes the return value of the entire try
我正在尝试用 JavaScript 制作一个基本的井字棋类型游戏。尽管 x 和 y 值在 if 语句的范围内,但除最后一个之外的所有空格都有效。 我不知道为什么最后的 else if 语句不起作用。
我想知道如何使用PowerMock模拟kotlin最终类(class),以便进行测试。我按照指南测试了Java最终类,但仍然出现此错误 Cannot subclass final class 有什么办
考虑以下设置: // debugger class public class Debug { // setting public final static boolean DEBUG
给定以下类(class): public class SomeClass { private final int a; public SomeClass(int a) {
This question already has answers here: What does “final” do if you place it before a variable?
我有一个类PasswordEncryptor,它使用org.jasypt.util.password.StrongPasswordEncryptor作为其字段之一,因为我试图使应用程序“可集群”所有类
我今天有一个关于 StreamReader 类的问题。具体使用文件名参数初始化此类例如: TextReader tr = new StreamReader(fileName); 显然,当此操作完成后,
我想弄清楚什么是使用带锁的 try/finally 的最佳方式。 当我在同一个地方有 lock() 和 unlock() 时,我只使用 try/finally block 作为 JavaDoc还建议:
在 Java 中序列化后是否可以将 final transient 字段设置为任何非默认值?我的用例是一个缓存变量——这就是它是 transient 的原因。我还有一个习惯,就是制作不会改变的 Map
在this问题说 final transient 字段在序列化后不能设置为任何非默认值。那么,为什么我为 aVar1 变量设置了 3,为 aVar3 变量设置了 s3? import java.io.
在Xbox上进行开发时,我使用的是F#规范中最终工作流程的修改版。 Xbox上的.net框架似乎不支持尾部调用。因此,我必须在编译时禁用尾部调用优化。 尽管起初看来这种限制会阻止在计算表达式中使用任何
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我想让我的带有自定义对象的ArrayList成为最终对象,以便对象在设置后无法更改。 我试图这样声明它: private final ArrayList XML = new ArrayList();
我有一个场景,我需要类似于 .NET 的 try-catch-finally block 的内容。 在我的尝试中,我将创建一个#temp表,向其中插入数据并基于#temp处理其他数据集。 先是CATC
对此可能有一个简单的答案,但尝试充分使用 Butterknife,将一些 findViewById 转换为 @BindViews,并注意到我无法在需要声明为 Final 的 View 上使用 Bind
我是一名优秀的程序员,十分优秀!