使用 NSStringFromSelector 通过网络发送方法

发布于 2024-12-09 15:11:48 字数 755 浏览 0 评论 0原文

我目前正在使用两台计算机(mac1 和 mac2)使用 Objective-C 进行一些模拟的客户端-客户端方法。

我有一个客户端类,每台计算机上都有一个“客户端”实例(客户端1,客户端2)。我希望两个客户端都会同步:除了内存位置之外,它们都是相同的。

当用户在 mac1 上按下某个键时,我希望 client1 和 client2 都从类 Client 接收给定的方法(以便它们同步,即除了每台 mac 上的内存位置之外,它们都是相同的)。

对于这种方法,我当前的想法是创建 2 个方法:

- (void) sendSelector:(Client*)toClient,...;
- (void) receiveSelector:(Client*)fromClient,...;

sendSelector:使用 NSStringFromSelector() 将方法转换为 NSString,并通过网络发送它(现在我们不用担心通过网络发送字符串)。

另一方面,receiveSelector:使用 NSSelectorFromString() 将 NSString 转换回选择器。

我的第一个问题/议题是:这种方法在 Objective-c 网络上的“标准”程度如何?

我的第二个问题:

该方法的参数是什么?有没有办法“打包”给定的类实例并通过网络发送它?我理解打包时指针的问题,但是我的程序中的每个实例都是唯一的标识,因此这应该没有问题,因为两个客户端都知道如何从其标识中检索对象。

感谢您的帮助

I'm currently making a client-client approach on some simulation with objective-c with two computers (mac1 and mac2).

I have a class Client, and every computer has a instance of the "Client" on it (client1,client2). I expect that both clients will be synchronized: they will both be equal apart from memory locations.

When a user presses a key on mac1, I want both client1 and client2 to receive a given method from class Client (so that they are synchronized, i.e. they are the same apart from it's memory location on each mac).

To this approach, my current idea is to make 2 methods:

- (void) sendSelector:(Client*)toClient,...;
- (void) receiveSelector:(Client*)fromClient,...;

sendSelector: uses NSStringFromSelector() to transform the method to a NSString, and send it over the network (let's not worry about sending strings over net now).

On the other hand, receiveSelector: uses NSSelectorFromString() to transform a NSString back to a selector.

My first question/issue is: to what extent is this approach "standard" on networking with objective-c?

My second question:

And the method's arguments? Is there any way of "packing" a given class instance and send it over the network? I understand the pointer's problem when packing, but every instance on my program as an unique identity, so that should be no problem since both clients will know how to retrieve the object from its identity.

Thanks for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

悲凉≈ 2024-12-16 15:11:48

我先回答你的第二个问题:

该方法的参数呢?有没有什么方法可以“打包”给定的
类实例并通过网络发送它?

许多 Cocoa 类实现/采用 NSCoding @protocol。这意味着它们支持一些用于序列化为字节流的默认实现,然后您可以通过网络发送该字节流。强烈建议您使用 NSCoding 方法,除非由于某种原因它根本不适合您的需求。 (即使用完成工作的最高抽象级别)

现在谈谈第一个问题的哲学方面;我将您的问题改写为“使用序列化方法调用作为网络上两个客户端之间的通信手段是一种好方法吗?”

首先,您应该知道 Objective-C 有一个不经常使用但相当完整的实现,用于处理具有高抽象级别的机器之间的远程调用。它被称为分布式对象。苹果似乎在某种程度上将其隐藏起来(有充分的理由 - 继续阅读),但我能够找到 分布式对象编程主题指南。您可能会发现它内容丰富。 AFAIK,分布式对象的所有基础仍然在 Objective-C 运行时/框架中提供,所以如果你想使用它,如果只是为了原型,你可能可以。

我无法推测您现在似乎无法在developer.apple.com 上找到此文档的确切原因,但我认为可以公平地说,一般来说,您不想使用在生产中或通过不安全的网络通道(例如:通过互联网)进行此类远程调用方法。这是一个巨大的潜在攻击媒介。试想一下:如果我可以修改或欺骗您的网络消息,我就可以诱导您的客户端应用程序使用任意参数调用任意选择器。不难看出这会导致非常错误。

在较高的层面上,让我建议为您的应用程序提供某种协议,具有某种任意的有线格式(另一个人提到了 JSON——现在它得到了很多支持——但是使用 NSCoding 可能会以最快的速度引导您),当您的客户端收到这样的消息时,它应该将消息作为数据读取并决定要采取什么操作,而不是在运行时实际派生出什么是有效的代码 来自消息本身。

从“把事情做好”的角度来看,我喜欢分享我不久前学到的一句格言:“让它工作;让它工作正确;让它工作快速。按照这个顺序。”

对于原型设计,也许您不关心安全性。也许当您只是想“使其工作”时,您可以使用分布式对象,或者您可以推出自己的远程调用协议,正如您一直在考虑做的那样。请记住:在将其发布到野外之前,您确实需要“使其正常工作”,否则您为原型制作而做出的那些决定可能会让您付出高昂的代价。这里最好的方法是创建一个类或一组类,从代码的其余部分中抽象出网络协议和线路格式,这样您就可以稍后更换网络实现,而无需触及全部你的代码。

还有一个建议:我在您最初的问题中读到“在多个客户端之间保持对象(或者可能是对象图)同步”的愿望。这是一个复杂的主题,但您可能希望采用“命令模式”(请参阅​​《四人帮》一书,或任何其他野外处理方法。)采用这种方法也可能本质上为您的网络协议带来结构。换句话说,一旦您将所有模型突变操作分解为“命令”,您的协议可能就像使用 NSCoding 序列化这些命令并将它们通过线路传送到另一个客户端并在那里再次执行它们一样简单。

希望这会有所帮助,或者至少为您提供一些起点和需要考虑的事项。

Let me address your second question first:

And the method's arguments? Is there any way of "packing" a given
class instance and send it over the network?

Many Cocoa classes implement/adopt the NSCoding @protocol. This means they support some default implementation for serializing to a byte stream, which you could then send over the network. You would be well advised to use the NSCoding approach unless it's fundamentally not suited to your needs for some reason. (i.e. use the highest level of abstraction that gets the job done)

Now for the more philosophical side of your first question; I'll rephrase your question as "is it a good approach to use serialized method invocations as a means of communication between two clients over a network?"

First, you should know that Objective-C has a not-often-used-any-more, but reasonably complete, implementation for handling remote invocations between machines with a high level of abstraction. It was called Distributed Objects. Apple appears to be shoving it under the rug to some degree (with good reason -- keep reading), but I was able to find an old cached copy of the Distributed Objects Programming Topics guide. You may find it informative. AFAIK, all the underpinnings of Distributed Objects still ship in the Objective-C runtime/frameworks, so if you wanted to use it, if only to prototype, you probably could.

I can't speculate as to the exact reasons that you can't seem to find this document on developer.apple.com these days, but I think it's fair to say that, in general, you don't want to be using a remote invocation approach like this in production, or over insecure network channels (for instance: over the Internet.) It's a huge potential attack vector. Just think of it: If I can modify, or spoof, your network messages, I can induce your client application to call arbitrary selectors with arbitrary arguments. It's not hard to see how this could go very wrong.

At a high level, let me recommend coming up with some sort of protocol for your application, with some arbitrary wire format (another person mentioned JSON -- It's got a lot of support these days -- but using NSCoding will probably bootstrap you the quickest), and when your client receives such a message, it should read the message as data and make a decision about what action to take, without actually deriving at runtime what is, in effect, code from the message itself.

From a "getting things done" perspective, I like to share a maxim I learned a while ago: "Make it work; Make it work right; Make it work fast. In that order."

For prototyping, maybe you don't care about security. Maybe when you're just trying to "make it work" you use Distributed Objects, or maybe you roll your own remote invocation protocol, as it appears you've been thinking of doing. Just remember: you really need to "make it work right" before releasing it into the wild, or those decisions you made for prototyping expedience could cost you dearly. The best approach here will be to create a class or group of classes that abstracts away the network protocol and wire format from the rest of your code, so you can swap out networking implementations later without having to touch all your code.

One more suggestion: I read in your initial question a desire to 'keep an object (or perhaps an object graph) in sync across multiple clients.' This is a complex topic, but you may wish to employ a "Command Pattern" (see the Gang of Four book, or any number of other treatments in the wild.) Taking such an approach may also inherently bring structure to your networking protocol. In other words, once you've broken down all your model mutation operations into "commands" maybe your protocol is as simple as serializing those commands using NSCoding and shipping them over the wire to the other client and executing them again there.

Hopefully this helps, or at least gives you some starting points and things to consider.

淡淡绿茶香 2024-12-16 15:11:48

如今,最标准的方法似乎是将所有内容打包到 JSON 上。

These days it would seem that the most standard way is to package everything up on JSON.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文