- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设你有一个 UIView
显示来自某个模型对象的数据。当模型在后台发生变化时,它会通过某种订阅机制通知其监听器;一个很常见的模式...
我在 iOS 上一直在做的是订阅 ViewControllers
中的模型通知。 viewWillAppear
;刷新相应的 View 以响应更改通知;并在 viewWillDisappear
中停止我的订阅.这样,当给定的 View Controller 离开屏幕时,通过跟踪更改来确保我不会浪费资源,所以我对这个解决方案很满意。
但是,我当前的项目需要一些 View 来跟踪模型对象,并且它们在多个 View Controller 中到处使用。如果我使用以前的方法,那么订阅/取消订阅管道将不得不在许多 View Controller 中复制。我想知道,这种逻辑是否可以放在 View 本身中?虽然 UIView's
生命周期事件(willMoveToSuperview: 和 willMoveToWindow:) 在这方面有一些模糊的语义,这必须是可能的,因为这就是 Apple 对 iAd 显示 View 所做的 - 即 ADBannerView 不需要任何管道来开始显示广告,除了放置它在您的 View 层次结构中,并且它从远程源中提取数据,因此它不能通过对 iAd 服务器进行不必要的订阅来浪费资源。
有没有人做过这件事? IE。将昂贵的变更跟踪机制与 UIView
可靠地耦合在一起生命周期事件?
最佳答案
尽管使用 viewDidAppear
,但我经常使用此过程因为我不能确定其他 View Controller 不会调用 viewWillAppear
在当前的 viewWillDisappear
之前将被调用,当您将委托(delegate)分配给某个“共享实例”时,这可能会带来不便。
无论如何,我总是使用 View Controller 来处理这种重新加载,然后调用特定的 View 进行刷新。我在 removeFromSuperView
中退订了一些特定情况。方法,但您可以理解这不是最好的方法,因为 View 可以作为 subview 再次添加到某个 View 中,并且订阅不会自动完成。但话又说回来,在 View 本身由于订阅而自我保留的情况下,我确实使用了这个,最常见的情况是使用计时器或显示链接(这可以再次通过使用 2 个类来避免,但这是另一回事)。
如果在 View Controller 级别上使用此订阅/取消订阅,例如检查 View 是否确实可见,我建议您将其保留在那里并手动订阅/取消订阅 View Controller 拥有的 View 。如果没有其他原因,您的代码将更易于管理。
另一方面,如果这需要在某些特定 View 类型的级别上(创建一个库甚至只是简单地重用),那么我会尝试在某些 init
中处理这个问题。和 dealloc
方法。同样,如果资源紧张,我会将逻辑移至 View Controller 。
无论如何,如果您找到一个可靠的解决方案,将这个逻辑严格地放在 View 中,我会很高兴听到它。
编辑评论以添加自保留解决方案:
当涉及到一个类被订阅保留的问题时,例如计时器或通知中心,您所做的是创建 2 个类。一个代表您的接口(interface)并具有获取特定数据所需的所有方法,并且如果需要包含调用者可以订阅的委托(delegate)(具有弱链接),我们将其称为 A 类。现在该类包含另一个包含实际的类订阅外部资源,例如通知中心,并且是自保留的,B类。所以A类不是自保留的,因为它没有直接订阅通知中心,计时器......这意味着A类将被正确释放,而B类将持续存在并导致潜在的内存泄漏。然后 B 类确实需要取消订阅的显式调用,因此它被释放,这应该在 A 类中完成 dealloc
方法。
我想简单的解释可能有点复杂,所以看看这段代码:
#import "ClassA.h"
@class ClassA;
@class ClassB;
@protocol ClassBDelegate <NSObject>
- (void)classBPing:(ClassB *)sender;
@end
@interface ClassB : NSObject
@property NSTimer *timer;
@property (weak) id<ClassBDelegate> delegate;
- (void)beginNotificationHandling;
- (void)endNotificationHandling;
@end
@implementation ClassB
- (void)beginNotificationHandling {
if(self.timer == nil) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}
}
- (void)endNotificationHandling {
[self.timer invalidate];
self.timer = nil;
}
- (void)onTimer {
[self.delegate classBPing:self];
}
@end
@interface ClassA()<ClassBDelegate>
@property ClassB *classBInstance;
@end
@implementation ClassA
- (instancetype)init {
if((self = [super init])) {
self.classBInstance = [[ClassB alloc] init];
self.classBInstance.delegate = self;
[self.classBInstance beginNotificationHandling];
}
return self;
}
- (void)dealloc {
// once this class is deallocated the classB instance must be invalidated so it is deallocated as well
[self.classBInstance endNotificationHandling];
}
- (void)classBPing:(ClassB *)sender {
NSLog(@"Ping");
}
@end
classB
在头文件中,因为您不应该在
classA
之外使用它一点也不。现在使用此过程,您可以添加任何方法、委托(delegate)或来自
classA
的任何内容。处理事件。
关于ios - 为 UIView 提供数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26605566/
初学者 android 问题。好的,我已经成功写入文件。例如。 //获取文件名 String filename = getResources().getString(R.string.filename
我已经将相同的图像保存到/data/data/mypackage/img/中,现在我想显示这个全屏,我曾尝试使用 ACTION_VIEW 来显示 android 标准程序,但它不是从/data/dat
我正在使用Xcode 9,Swift 4。 我正在尝试使用以下代码从URL在ImageView中显示图像: func getImageFromUrl(sourceUrl: String) -> UII
我的 Ubuntu 安装 genymotion 有问题。主要是我无法调试我的数据库,因为通过 eclipse 中的 DBMS 和 shell 中的 adb 我无法查看/data/文件夹的内容。没有显示
我正在尝试用 PHP 发布一些 JSON 数据。但是出了点问题。 这是我的 html -- {% for x in sets %}
我观察到两种方法的结果不同。为什么是这样?我知道 lm 上发生了什么,但无法弄清楚 tslm 上发生了什么。 > library(forecast) > set.seed(2) > tts lm(t
我不确定为什么会这样!我有一个由 spring data elasticsearch 和 spring data jpa 使用的类,但是当我尝试运行我的应用程序时出现错误。 Error creatin
在 this vega 图表,如果我下载并转换 flare-dependencies.json使用以下 jq 到 csv命令, jq -r '(map(keys) | add | unique) as
我正在提交一个项目,我必须在其中创建一个带有表的 mysql 数据库。一切都在我这边进行,所以我只想检查如何将我所有的压缩文件发送给使用不同计算机的人。基本上,我如何为另一台计算机创建我的数据库文件,
我有一个应用程序可以将文本文件写入内部存储。我想仔细看看我的电脑。 我运行了 Toast.makeText 来显示路径,它说:/数据/数据/我的包 但是当我转到 Android Studio 的 An
我喜欢使用 Genymotion 模拟器以如此出色的速度加载 Android。它有非常好的速度,但仍然有一些不稳定的性能。 如何从 Eclipse 中的文件资源管理器访问 Genymotion 模拟器
我需要更改 Silverlight 中文本框的格式。数据通过 MVVM 绑定(bind)。 例如,有一个 int 属性,我将 1 添加到 setter 中的值并调用 OnPropertyChanged
我想向 Youtube Data API 提出请求,但我不需要访问任何用户信息。我只想浏览公共(public)视频并根据搜索词显示视频。 我可以在未经授权的情况下这样做吗? 最佳答案 YouTube
我已经设置了一个 Twilio 应用程序,我想向人们发送更新,但我不想回复单个文本。我只是想让他们在有问题时打电话。我一切正常,但我想在发送文本时显示传入文本,以确保我不会错过任何问题。我正在使用 p
我有一个带有表单的网站(目前它是纯 HTML,但我们正在切换到 JQuery)。流程是这样的: 接受用户的输入 --- 5 个整数 通过 REST 调用网络服务 在服务器端运行一些计算...并生成一个
假设我们有一个名为 configuration.js 的文件,当我们查看内部时,我们会看到: 'use strict'; var profile = { "project": "%Projec
这部分是对 Previous Question 的扩展我的: 我现在可以从我的 CI Controller 成功返回 JSON 数据,它返回: {"results":[{"id":"1","Sourc
有什么有效的方法可以删除 ios 中 CBL 的所有文档存储?我对此有疑问,或者,如果有人知道如何从本质上使该应用程序像刚刚安装一样,那也会非常有帮助。我们正在努力确保我们的注销实际上将应用程序设置为
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我正在为服务于发布请求的 API 调用运行单元测试。我正在传递请求正文,并且必须将响应作为帐户数据返回。但我只收到断言错误 注意:数据是从 Azure 中获取的 spec.js const accou
我是一名优秀的程序员,十分优秀!