Ios 比将NSDictionary作为参数传递更好的模式?

Ios 比将NSDictionary作为参数传递更好的模式?,ios,objective-c,macos,model-view-controller,design-patterns,Ios,Objective C,Macos,Model View Controller,Design Patterns,随着我们的代码库的成熟,我开始不喜欢使用传递字典的模式来打包消息传递信息,或者更糟糕的是,传递函数参数。它要求发送和接收函数都具有未记录的字符串文本API ..in some function.. NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: thisObject, @"thisKey", thatObject,

随着我们的代码库的成熟,我开始不喜欢使用传递字典的模式来打包消息传递信息,或者更糟糕的是,传递函数参数。它要求发送和接收函数都具有未记录的字符串文本API

..in some function..
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:
                         thisObject, @"thisKey",
                         thatObject, @"thatKey",
                         nil];

[[NSNotificationCenter defaultCenter] postNotificationName:@"MY_NOTIFICATION" object:nil userInfo:info];
....
然后在
someClass
的侦听器中

- (void)someClassListener:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];

    ThisObject *ob1 = [info objectForKey:@"thisKey"];
    ThatObject *ob2 = [info objectForKey:@"thatKey"];
}
您必须记住,
thisKey
thatKey
是类型为
ThisObject
ThatObject
的键。对于该通知,您可以为这些键创建一些常量,但这并不能真正解决问题

假设你有一个需要15个参数的函数,你不需要一个有15个参数的函数,只需要传递一个字典就容易多了(虽然可读性较差),但是现在你遇到了与上面相同的问题

我在这些类的头文件(即一个头文件中有两个接口)中创建了一个存根的“消息类”,消息类只是一个对象列表,您可以定义这些对象并将其发送给创建更强大契约的方法,但这感觉不对

如果我能在标题中做一些类似于
typeDef
的参数对象,但不支持
NSObject
的东西,比如
int
float
等,那就太好了


本质上,我试图在消息发送者和消息接收者之间创建一个更强的契约,无论是函数还是通知。您可以为键定义常量。例如,有关示例,请参见
UIKeyboardDidShowNotification
的文档。有一个指向所有键的链接,可用于获取有关通知的信息

更好的方法是将数据封装到类而不是字典中。创建一个具有属性的简单类。这将比一本字典更能自我记录。您可以在.h文件中看到属性名称和属性类型


如果您发现有需要15个参数的方法,则需要后退一步,并将这些参数封装到适当的类中。也许该方法可以适当地简化为几个参数和一个类或类似的东西。

您需要的是一个参数对象,一个封装了一系列字段的小对象,以便与其他类进行方便的通信。在内部,参数对象可能包含一个字典,或者只是一组指定的字段

为参数对象提供一个简单的API,让这两个类都可以设置和获取您使用的特定字段——setThisKey:和getThisKey。本质上,它记录了方法和类之间的API

接下来,寻找将功能移动到参数对象中的机会。例如,如果您有如下内容:

 param.fieldSize=[self.data size];
 param.fieldColor=[self.data color];
 param.flavor=[self.data lookUpTheRecipe]
你可以用

 [param withField: self.data];

通过工作,您通常可以使参数对象执行许多有用的工作;这可以分解长方法并帮助大型类摆脱多余的责任。

首先,有15个参数是不好的,在这种情况下,您应该考虑不进行此类回调或尝试减少数量


使用通知的发送者怎么样?例如,您的对象
任务
已完成并发送通知。接收方使用发送方访问
发送方.result
发送方.error
发送方.anything


如果您希望这些对象(发送者/接收者)之间有更紧密的联系,那么您应该使用其他通信方式,而不是
NSNotifications

一些备选方案:

  • 委托(或其他类型的直接方法调用)
  • 目标+行动

通过将它们存储在一个数组中,它们都可以用于许多回调,并且它们不使用
nsdictionary
进行值传递。

我提到键的常量并不是一个好的解决方案,因为您仍然需要查找键是什么,而不是为值(对象)将是什么创建一个强大的契约,更像是一个建议。将数据封装到类中是我正在研究的一个方向,但是为我想要传递的每一条消息创建一个类似乎很麻烦,如果两个参数都是10,你同意吗?@Shizam,如果这些消息被放入不同的字典中,那么你可能需要多个类。但是,如果您谈论的消息有时从字典传递两个键,有时传递10个键,那么这仍然只是一个类对象。@rdelmar在我们的程序中,我们可能有10-15个唯一的通知,每个通知都需要自己的类来定义消息等的属性。看起来最好的方法就是使用“消息类”。我提到这是我正在研究的一个解决方案,我看到的问题是必须为每个消息创建一个参数对象,这似乎很麻烦。此外,似乎将该对象放在“拥有”消息的类的头中,这样一个头中就有两个接口,这似乎是不受欢迎的。您通常可以在多个相关方法中共享一个参数对象。我不反对将接口添加到类头的帮助对象。但是,使用参数对象的目标是向该对象添加许多有用的行为,而不仅仅是包装一些数据。因此,最终,参数对象可能会在世界上占有一席之地。像NSURL这样的类就是这样开始的。我们也使用委托和块,我只是用NSNotifications作为一个很容易看到问题的例子。我仍然有块等的问题,但我开始认为创建参数对象来包含参数几乎是唯一的方法。