Better than passing NS dictionaries as parameters?

As our codebase matures, I don’t like the dictionary transfer pattern as a way to package information for sending messages or, worse, function arguments. This requires a send and receive function that has an undocumented string literal API.

..in some function.. NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: thisObject, @"thisKey", thatObject, @"thatKey", nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MY_NOTIFICATION" object:nil userInfo:info]; .... 

and then in someClass listener

 - (void)someClassListener:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; ThisObject *ob1 = [info objectForKey:@"thisKey"]; ThatObject *ob2 = [info objectForKey:@"thatKey"]; } 

You must remember that thisKey and thatKey are keys such as ThisObject and ThatObject for this notification, of course, you can create some constants somewhere for these keys, but this does not really solve the problem.

And let's say that you have a function that requires 15 arguments, you are not going to create a function with 15 parameters, it would be much easier (although less readable) just to pass the dictionary, but now you have the same problem, as mentioned above.

I played with creating the missing “message classes” in these header files of this class (i.e. two interfaces in one header), and the message class is just a list of objects that you define and send to a method that creates a stronger contract but that seems wrong.

It would be great if I could do something like the typeDef of the parameter object in the header, but this does not support NSObject only things like int or float , etc.

In fact, I'm trying to create a stronger contract between the sender of the message and the receiver of messages, whether it be functions or notifications.

+6
source share
3 answers

You can define constants for keys. For an example, see Documents for UIKeyboardDidShowNotification for an example. There is a link to all keys that can be used to receive notification information.

A better approach would be to encapsulate your data in a class instead of a dictionary. Create a simple class with properties. It will be much more self-documenting than a dictionary. You can see the property names and property types in the .h file.

If you find that you have methods that require 15 arguments, you need to step back and encapsulate these arguments in the appropriate class. Perhaps the method correctly boils down to a few arguments and a class or something similar.

+4
source

What you want is a parameter object, a small object that encapsulates a bunch of fields for convenient communication with some other class. Internally, a parameter object may contain a dictionary or just a set of assigned fields.

Give the parameter object a simple API that allows you to set both classes and get the specific fields that you use - setThisKey: and getThisKey. This essentially documents the API between methods and classes.

Then find opportunities to move the functionality into the parameter object. For example, if you have something like this:

  param.fieldSize=[self.data size]; param.fieldColor=[self.data color]; param.flavor=[self.data lookUpTheRecipe] 

You can encapsulate it all with

  [param withField: self.data]; 

When working, you can often make a parameter object a useful job; this can destroy long methods and help large classes get rid of unnecessary duties.

+2
source

Firstly, having 15 arguments is not good, and in that case you should consider not making such callbacks or trying to reduce the number.


How about using a notification sender? For example, your Task object is completed and sends a notification. The receiver uses the sender to access sender.result , sender.error , sender.anything .


If you need a stronger contact between these objects (sender / receiver), perhaps you should use a different communication method instead of NSNotifications .

Some alternatives:

  • delegate (or some other direct method invocation method)
  • blocks
  • target + action

All of them can be used as many callbacks, storing them in an array, and they do not use NSDictionaries to pass the value.

0
source

All Articles