我试图找出最智能,最可靠的方法,使我可以为多个视图控制器访问检索到的PubNub历史记录。正如我所知,有多种方法可以做到这一点,但在我阅读了一堆问题和文章后,我无法确定哪种解决方案最好。实际上我认为依赖注入在我的情况下是正确的想法,但我不确定,因为我在示例PubNub应用程序中看到了不同的解决方案,总体而言我从未听说过,所以我会避免它,如果它'可能。
可能的方式:
1。使用AppDelegate
这可能是最简单的方法,但很多开发人员说,AppDelegate确实不是存储全球数据的最佳位置。所以我不喜欢这样做。
2。使用Singleton
作为一个例子,我在PubNub的iPad演示应用程序( PNDataManager 文件)中看到了这个解决方案。我确信这是最好的方式,但在我阅读Stephen Poletto's article on objc.io about singletons之后我改变了主意,因为他指出了一些问题,这在我的案例中可能很重要。
这是一篇非常有用的文章,值得一读,但实际上我只会抓住在我的情况下发现重要的想法。
"假设我们正在构建一个应用程序,用户可以在其中查看其列表 朋友。他们的每个朋友都有个人资料图片,我们想要的 应用程序能够在设备上下载和缓存这些图像。使用dispatch_once片段,我们可能会发现自己编写了一个SPThumbnailCache单例"
假设我们想要缓存message
数组而不是我们在名为[PubNub requestFullHistoryForChannel: withCompletionBlock:^(NSArray *message, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error)}];
的根视图控制器中使用此方法ViewController1
检索的图像。
"我们继续构建应用程序,一切似乎都在世界上, 直到有一天,当我们决定实施'退出'的时候 功能,因此用户可以在应用程序内切换帐户。突然, 我们手上有一个讨厌的问题:用户特定的状态存储在 全球单身人士。当用户退出应用程序时,我们希望成为 能够清理磁盘上的所有持久状态。否则,我们会离开 在用户设备上的孤立数据背后,浪费了宝贵的磁盘 空间。如果用户注销然后登录新帐户, 我们还希望能够为新的SPThumbnailCache 用户。这里的问题是,根据定义,单身人士被假定为“创造一次,永远活着”的实例。您可以想象一些上述问题的解决方案。也许我们可以在用户退出时拆除单例实例
这里的问题是,根据定义,单身人士被认为是 “创造一次,永远活着”的例子。你可以想象一些 解决上述问题的方法。也许我们可以拆掉 用户注销时的单例实例。我们当然可以使这个解决方案工作,但成本太高了。首先,我们已经失去了dispatch_once解决方案的简单性,这是一种保证线程安全的解决方案,并且所有调用[SPThumbnailCache sharedThumbnailCache]的代码只能获得相同的实例。我们现在需要非常小心利用缩略图缓存的代码的代码执行顺序....由于单例实例没有明确的所有者(即单例管理自己的生命周期),因此变得非常困难。关闭'单身人士'。 这里的教训是,单身人士只应保留为全球状态,而不是与任何范围相关联。如果state的范围缩短到比“我的应用程序的完整生命周期”短的任何会话,那么该状态不应该由单例管理。管理用户特定状态的单例是代码味道,你应该批判性地重新评估你的设计对象图。"
当用户登录新帐户时,我们应该可以 构建并与全新的SPThumbnailCache交互,没有 注意破坏旧的缩略图缓存。老人 应该懒洋洋地清理视图控制器和旧缩略图缓存 在后台根据自己的典型规则自行决定 对象管理。简而言之,我们应该孤立相关的国家 与来自与用户B相关联的州的用户A。
我知道一个NSArray
个PNMessage
个对象,但不包含图片并不相同,而且处理起来也比较容易,但我真的很困惑我应该如何处理它们。
最初我会将message
内的requestFullHistoryForChannel: withCompletionBlock:
变量传递给名为self.messageGlobal
的实例变量(我可以在每个视图中使用单例)并在用户登录时重置它进行。
//inside the viewWillAppear
[PubNub requestFullHistoryForChannel: withCompletionBlock:^(NSArray *message, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error)
// self.messageGlobal should be managed by a singleton or appdelegate or use the dependency injection??
self.messageGlobal = message;
}];
- (IBAction)logOutButton:(id)sender {
//disconnect from the PubNub network
[PubNub unsubscribeFromChannel:currentUserChannel];
//prepape ivar for the new message history
[self.messageGlobal removeAllObjects];
// log out user (i'm using parse.com for managing users)
[PFUser logOut]
}
在斯蒂芬的文章之后,我觉得我迷失了,如果有人能够解释正确的方向,那就太棒了。
我的计划是在ViewController1
中创建一个处理历史记录的方法。
-(void)downloadPubNubHistory {
[PubNub requestFullHistoryForChannel: withCompletionBlock:^(NSArray *message, PNChannel *channel, PNDate *fromDate, PNDate *toDate, PNError *error)
// self.messageGlobal should be managed by a singleton or appdelegate or use the dependency injection??
self.messageGlobal = message;
}];
}
在AppDelegate
或ViewController1
我会让观察者在当前用户频道收到新消息时收到通知,这很重要,因为我希望通话{{1}每当他或她收到新消息并使用新内容更新当前视图时。
downloadPubNubHistory
例如在[[PNObservationCenter defaultCenter] addMessageReceiveObserver:currentUserChannel withBlock:^(PNMessage * msg) {
[ViewController1 downloadPubNubHistory];
} }];
我列出 sampleUserB 发送到 sampleUserA (当前用户)频道的每条消息,如果 sampleUserA&# 39; s 频道在她/他的频道上收到来自 sampleUserB 的新消息我需要重新加载ViewController3
,并重新加载downloadPubNubHistory
,因为我' m过滤ViewController3
中的self.messageGlobal
以仅从ViewController3
获取消息。
任何意见和建议都欢迎,我可能误解了整个概念,我基本上可以使用单例并在每次用户注销时重置它而没有任何问题,但我想利用最轻量级的可靠性解。如果有任何其他推荐的技术,我也很乐意听。
答案 0 :(得分:1)
对我来说,单身人士总是一个为具体目的服务的工具。我没有看到多用户的任何故障事件以及基于单例的切换(你总是可以重置单身的状态而不是试图破坏它)。
因为我们在数据上工作很多,所以当我们需要使用它时,我们无法始终初始化某些数据模型,因为会花费额外的时间:分配和分配。初始化,预置初始状态,可能从文件系统或网络加载一些数据。如果我们将在我们想要使用数据操作的每个视图或数据对象中执行所有这些步骤 - 它将会破坏我们的应用程序响应能力,并且用户将有一些糟糕的体验。
所以,这一切都取决于你如何编码你的单身人士以及你将如何使用它。如果您有多用户应用程序,并且某些敏感数据应远离其他用户,您可以创建一些用户实体并将所有必需数据存储在其中(在您的情况下,消息可以传递给它)。这个实体将是一些简单的数据模型或数据对象,但仍然需要有一些类负责它。在这里,您可以创建一些单例,负责管理当前用户及其数据(当您指定当前用户时,旧的可以解除分配,并且所有数据都可以推送到某些本地存储,例如sqlite上的CoreData)。
据我所知,您聊天应用程序想要在登录后提取用户历史记录...您可以在课程中进行管理用户实体并在当前用户更改后立即获取历史记录(在您的示例中,每次调用历史记录API) ,当新消息到达用户时 - 糟糕的主意,因为历史API可能重)。您的PFUser实例可以存储所有必需的数据,以及应该订阅或取消订阅的频道,并且可以在 logOut 过程中使用它们。