我是Ruby的新手,来自Objective-C和Swift。
我遇到了一个问题,我有一个包含另一个对象的对象作为属性。第二个对象具有beginStream
函数,通过该函数从服务器流式传输数据,当它获取新数据时,它会产生,因此第一个对象可以响应。它看起来像这样:
class StreamManager
def initialize
@streams = Array.new
end
def setup_user_stream(user_id)
stream = Stream.new(user_id)
@streams << stream
stream.begin_stream do |message|
puts "A message was received: #{message}"
end
end
end
class Stream
def initialize(user_id)
@user_id = user_id
end
def begin_stream
Thread.new do
# Begins stream
@client = Stream::Client.new(user_id)
@client.on_error do
# need to let StreamManager know about this
end
@client.on_message do |message|
yield message if block_given?
end
end
end
end
现在我从流客户端获得了这个on_error
调用,我需要让我的StreamManager了解它。我该怎么做呢?
在Objective-C / Swift中,我有一个名为StreamDelegate的协议,该流将作为弱属性,然后StreamManager将Stream的委托设置为自身,并响应提供的功能。协议。因此,Stream将调用委托函数@delegate?.streamDidReceiveError
,并将流管理器设置为delegate
,并实现该函数,并将其调用。
我简化了这个例子 - Stream是Stream :: Client的抽象,它来自另一个库,并且还提供了许多其他消息。但是现在我正在写这篇文章,我想也许他们让我正在招揽那些不同的方块的方式就是要走的路。在这种情况下,我需要了解如何自己实现?或许这可能是设计我的班级的一种糟糕方式 - 我不知道?
答案 0 :(得分:1)
父StreamManager
可以将自身作为变量传递给子Stream
。
def initialize(stream_manager, user_id)
@stream_manager = stream_manager
@user_id = user_id
end
并在setup_user_stream中初始化它:
stream = Stream.new(self, user_id)
如果您想要稍微冗长的代码,可以使用命名关键字:
def initialize(:stream_manager, :user_id)
然后:
Stream.new(stream_manager: self, user_id: user_id)
答案 1 :(得分:1)
这里有几种不同的方法:
1)你仍然可以使用你在Cocoa中习惯的委托模式。唯一的区别是你没有正式的协议/接口。您的Stream将采用委托/回调处理程序对象,该对象是实现某些方法的任何对象。您可以通过在调用它们之前检查对象是否响应它们来使这些方法成为可选方法。您的StreamManager可以实现此接口并将其作为依赖项传递给流。
2)您可以在Stream类上定义错误和消息的回调,而不是将单个块传递给begin_stream方法。
3)保留现有的API,而不是产生消息,将消息或错误封装在Result对象中,然后生成它。我想这可能是我的首选。
很抱歉缺少代码示例,但我在iPhone上写这个。