+ (Planet *)createPlanetInContext:(NSManagedObjectContext *)context
withName:(NSString *)name
type:(NSString *)type
group:(NSString *)group
andDiameter:(NSNumber *)diameter {
If I wanted to encapsulate the arguments "name", "type", "group" and "diameter" into a single entity for passing to the above method what is the best type to use for encapsulation? The above method is just a quick example which you could argue is just fine as presented, but what if there were many more arguments that needed to be passed. I would need to package the data before calling the method so the solution needs to be something quick and simple to setup.
+ (Planet *)createPlanetWithData:(Data *)data inContext:(NSManagedObjectContext *)context {
Or is it more inline with objective-c practices (more readable) to individually list all the arguments?
I'd say generally you would want to individually list your arguments, for clarity. The sample method you've posted above isn't terribly long, in the context of Objective-C.
It's really to do with readability and documentation. When you list all the arguments it's clear to developers coming to your project what's being passed in where, and what kinds of objects are floating around. Automatic documentation generation (eg, Doxygen) also works off lists of arguments particularly well.
But there is a point at which, as you say, it becomes a little unwieldy. Twenty parameters to pass in and your method calls are going to be very, very long! So there are other options available - the easiest one is probably to use a NSDictionary or similar, which is used already in iOS to ferry certain bits of data around (particularly with notifications, where you have the userInfo dictionary).
Reading code is harder than writing code, so optimize for readability. Shortness of selectors should not be a factor; clarity should be.
Ask yourself which version is more readable, and stick to that one. I think it's relatively obvious that the version with the direct arguments is more readable.
Objective-C has wonderful syntax for methods with multiple arguments, so use this to your advantage. In a language with c-like syntax, I'd also hesitate to use many arguments.
You could populate a dictionary with one key/value pair per property on your NSManagedObject.
If you want to be super flexible, you could go with #Novarg's comment and pass a dictionary as your argument. That way, you can add parameters to it without affecting your method signature.
I have a particular preference for creating a custom args object to pass into my methods. This not only has the flexibility of a dictionary, but also may have some built-in utilities or additional logic. Also, unlike a dictionary, you don't need to hardcode key names and/or constants, and is MUCH easier to refactor if you, say, need to change a name of a property using Xcode's refactoring capabilities:
+ (Planet *)createPlanet:(PlanetArgs *)args
{
//args.context
//args.name
//args.type
//args.group
//args.diameter
//Args can even have some built-in logic
//planet.color = [args generateRandomColor]; <<-Just a rough idea
}
Related
In the MATLAB OOP framework, it can be useful to cast an object to a struct, i.e., define a function that takes an object and returns a struct with equivalent fields.
What is the appropriate place to do this? I can think of several options:
Build a separate converter object that takes care of conversions between various classes
Add a function struct to the class that does the conversion to struct, and make the constructor accept structs
Neither option seems to be very elegant: the first means that logic about the class itself is moved to another class. On the other hand, in the second case, it provokes users to use the struct function for any object, which will in general give a warning (structOnObject).
Are there altenatives?
Personally I'd go with the second option, and not worry about provoking users to call struct on other classes; you can only worry about your own code, not that of a third-party, even if the third party is MathWorks. In any case, if they do start to call struct on an arbitrary class, it's only a warning; nothing actually dangerous is likely to happen, it's just not a good practice.
But if you're concerned about that, you can always call your converter method toStruct rather than struct. Or perhaps the best (although slightly more complex) way might be to overload cast for your class, accepting and handling the option 'struct', and passing any other option through to builtin('cast',....
PS The title of your question refers to typecasting, but what your after here is casting. In MATLAB, typecasting is a different operation, involving taking the exact bits of one type and reinterpreting them as bits of another type (possibly an array of the output type). See doc cast and doc typecast for more information on the distinction.
The second option sounds much better to me.
A quick and dirty way to get rid of the warning would be disabling it by calling
warning('off', 'MATLAB:structOnObject')
at the start of your program.
The solutions provided in Sam Roberts' answer are however much cleaner. I personally would go for the toStruct() method.
I am learning Objective C and noticed this funky quirk while reading up on methods.
Like Java and C++, Obj.C can take in multiple parameters, which is fine, however it states that objective C methods can have multiple names which does not seem to register to well with me.
For instance:
-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;
In the above example, there are two parameters, bombLocation (return type CGPoint) and damaged (return type BOOL) and alongside the method name seems to be split as shipsatpoint:withDamage
I don't understand what's up with this...
What does it signify when it states that a method can have multiple names?
Is this applicable only for methods that require multiple parameters? Alternately, say I want to name my method with a single name but provide it with multiple parameters, is that possible or I must provide it with multiple names each of which correspond to a parameter? If yes, then why?
Thanks for jumping in with my confusion!!! :)
The reason is to make it easier to understand.
With your example, the method would be something like this in C++:
int shipsAtPointWithDamage (CGPoint bomb, BOOL damage) //I don't really know C++
OK, so the first parameter is the ship's point, and the damage is the second. It's easy enough to figure out, but that's the thing, you have to FIGURE it out, you have to look at the method to try and figure out what each thing is.
In Objective-C you have
-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;
Each parameter is clearly defined, the first is the ship's point, the second is damage. It reads like a sentence, whereas with C++ (and almost every other language) it doesn't.
If you want a method to have multiple parameters in Obj-C you have to write it this way:
-(returnType)paraOne:(type*)name paraTwo:(type*)name
It's something that just takes getting used to, every language is different. Once you get used to the way Objective-C does things, you'll think it's absolutely fantastic.
EDIT: and as filipe pointed out, because the method as multiple parameters it doesn't mean it has multiple names, in the example I gave above, the method name would be paraOne:paraTwo, NOT paraOne:
Objective-C uses a system of message passing based on selectors. This is not quite the same thing as method calling. When you see code like this:
[world shipsAtPoint:point withDamage:YES];
That is converted into the following C call (in the most common case):
objc_msgSend(world, #selector(shipsAtPoint:withDamage:), point, YES);
The #selector() construct returns a unique identifier. The exact format of that identifier is an internal implementation detail.
objc_msgSend includes quite a lot of logic in it's few dozen bytes of assembler. But in simplest case, it looks up the class for world, walks through a table of selectors until it finds the one that matches shipsAtPoint:withDamage: and then grabs the function pointer at that slot. It then jumps to that function pointer, leaving the rest of the parameters alone (in registers or on the stack as appropriate for the processor). The function at that location is your method, and it knows the order and types of its parameters based on your declaration.
What's important in all this for you is that the selector is shipsAtPoint:withDamage:. This is generally the one-and-only name of the method. There are not "multiple names" as you suggest. (Usually.... the Objective-C runtime is very powerful and it's possible to point multiple selectors to the same implementation.)
As Joe points out, a selector can be in the form foo::. This would represent a method that took two parameters and would be called like [world foo:point :YES]. You should never do this. It's incredibly confusing to read. But it's legal.
Here is the best explanation i've ever seen. It includes comparisons with C++/C as well as lots of other good info.
I think you are confused. A method cannot have multiple names, but the argument may be named differently in the header then they are in the implementation.
The name of that method is shipsAtPoint:withDamage:. This is also known as a selector.
This method returns an instance of NSArray, and accepts a CGPoint as the first argument, and a BOOL as the second argument.
The names of the arguments may differ, however. This is totally valid:
// .h file
-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;
// .m file
-(NSArray *)shipsAtPoint:(CGPoint)loc withDamage:(BOOL)dmg {
// ...
}
Lastly, ObjC is mainly some nice syntax sugar. You should know that any method invocation really just boils down to some C that looks more or less like this:
objc_msgSend(receiverObj, #selector(shipsAtPoint:withDamage:), point, damage);
So at the end of the day, you have a receiver, a selector, and your arguments. But the ObjC syntax is much nicer than that.
It is possible provide a method without labeled parameters but it is obviously discouraged.
-(void)badmethod:(id)obj1:(id)obj2:(id)obj3
{
}
//...
//Usage
[self badmethod:nil :nil :nil];
SEL sel = #selector(badmethod:::);
I have taken (with the authors permission on the site) a wrapper class for writing fetch requests to my Core Data stack.
The guy who wrote it says it has "optional parameters" and I wondered what this meant.
Anywho, the static methods are written as such...
+(NSMutableArray *) searchObjectsFromContext
: (NSString*) entityName
: (NSPredicate*) predicate
: (NSString*) sortKey
: (BOOL) sortAscending
: (NSManagedObjectContext *) managedObjectContext
I have been running it and passing "nil" into the unneeded params. Is this the correct thing to do?
Also, is there a significance to the fact that there is no extra method text between the colons?
Thanks for any help
Oliver
It's impossible to say if passing 'nil' is the correct thing to do without reading the documentation or examining the source code. It's probably correct, though, as that is standard behavior in most classes.
Creating method parameters without associated text (as you see in your posted code) is perfectly legal... but it's also perfectly ugly and you lose all the benefits of Obj-C's verbosity. There's absolutely no reason to write code like that, it only serves to make your classes more difficult to use.
Optional parameters are available in VB (and some other languages) but not C#. C# forces you to overload functions.
You can pass "default" values to the optional parameters if you like. As long as you know how the function will respond, I don't see how this will hurt anything.
EDIT: I just read your iphone tag.... sorry! I don't know how relevant my answer is to you in that regard
Currently I am making some decisions for my first objective-c API. Nothing big, just a little help for myself to get things done faster in the future.
After reading a few hours about different patterns like making categories, singletons, and so on, I came accross something that I like because it seems easy to maintain for me. I'm making a set of useful functions, that can be useful everywhere.
So what I did is:
1) I created two new files (.h, .m), and gave the "class" a name: SLUtilsMath, SLUtilsGraphics, SLUtilsSound, and so on. I think of that as kind of "namespace", so all those things will always be called SLUtils******. I added all of them into a Group SL, which contains a subgroup SLUtils.
2) Then I just put my functions signatures in the .h file, and the implementations of the functions in the .m file. And guess what: It works!! I'm happy with it, and it's easy to use. The only nasty thing about it is, that I have to include the appropriate header every time I need it. But that's okay, since that's normal. I could include it in the header prefix pch file, though.
But then, I went to toilet and a ghost came out there, saying: "Hey! Isn't it better to make real methods, instead of functions? Shouldn't you make class methods, so that you have to call a method rather than a function? Isn't that much cooler and doesn't it have a better performance?" Well, for readability I prefer the functions. On the other hand they don't have this kind of "named parameters" like methods, a.f.a.i.k..
So what would you prefer in that case?
Of course I dont want to allocate an object before using a useful method or function. That would be harrying.
Maybe the toilet ghost was right. There IS a cooler way. Well, for me, personally, this is great:
MYNAMESPACECoolMath.h
#import <Foundation/Foundation.h>
#interface MYNAMESPACECoolMath : NSObject {
}
+ (float)randomizeValue:(float)value byPercent:(float)percent;
+ (float)calculateHorizontalGravity:(CGPoint)p1 andPoint:(CGPoint)p2;
// and some more
#end
Then in code, I would just import that MYNAMESPACECoolMath.h and just call:
CGFloat myValue = [MYNAMESPACECoolMath randomizeValue:10.0f byPercent:5.0f];
with no nasty instantiation, initialization, allocation, what ever. For me that pattern looks like a static method in java, which is pretty nice and easy to use.
The advantage over a function, is, as far as I noticed, the better readability in code. When looking at a CGRectMake(10.0f, 42.5f, 44.2f, 99.11f) you'll may have to look up what those parameters stand for, if you're not so familiar with it. But when you have a method call with "named" parameters, then you see immediately what the parameter is.
I think I missed the point what makes a big difference to a singleton class when it comes to simple useful methods / functions that can be needed everywhere. Making special kind of random values don't belong to anything, it's global. Like grass. Like trees. Like air. Everyone needs it.
Performance-wise, a static method in a static class compile to almost the same thing as a function.
Any real performance hits you'd incur would be in object instantiation, which you said you'd want to avoid, so that should not be an issue.
As far as preference or readability, there is a trend to use static methods more than necessary because people are viewing Obj-C is an "OO-only" language, like Java or C#. In that paradigm, (almost) everything must belong to a class, so class methods are the norm. In fact, they may even call them functions. The two terms are interchangeable there. However, this is purely convention. Convention may even be too strong of a word. There is absolutely nothing wrong with using functions in their place and it is probably more appropriate if there are no class members (even static ones) that are needed to assist in the processing of those methods/functions.
The problem with your approach is the "util" nature of it. Almost anything with the word "util" it in suggests that you have created a dumping ground for things you don't know where to fit into your object model. That probably means that your object model is not in alignment with your problem space.
Rather than working out how to package up utility functions, you should be thinking about what model objects these functions should be acting upon and then put them on those classes (creating the classes if needed).
To Josh's point, while there is nothing wrong with functions in ObjC, it is a very strongly object-oriented language, based directly on the grand-daddy of object-oriented languages, Smalltalk. You should not abandon the OOP patterns lightly; they are the heart of Cocoa.
I create private helper functions all the time, and I create public convenience functions for some objects (NSLocalizedString() is a good example of this). But if you're creating public utility functions that aren't front-ends to methods, you should be rethinking your patterns. And the first warning sign is the desire to put the word "util" in a file name.
EDIT
Based on the particular methods you added to your question, what you should be looking at are Categories. For instance, +randomizeValue:byPercent: is a perfectly good NSNumber category:
// NSNumber+SLExtensions.h
- (double)randomizeByPercent:(CGFloat)percent;
+ (double)randomDoubleNear:(CGFloat)percent byPercent:(double)number;
+ (NSNumber *)randomNumberNear:(CGFloat)percent byPercent:(double)number;
// Some other file that wants to use this
#import "NSNumber+SLExtensions.h"
randomDouble = [aNumber randomizeByPercent:5.0];
randomDouble = [NSNumber randomDoubleNear:5.0 byPercent:7.0];
If you get a lot of these, then you may want to split them up into categories like NSNumber+Random. Doing it with Categories makes it transparently part of the existing object model, though, rather than creating classes whose only purpose is to work on other objects.
You can use a singleton instance instead if you want to avoid instantiating a bunch of utility objects.
There's nothing wrong with using plain C functions, though. Just know that you won't be able to pass them around using #selector for things like performSelectorOnMainThread.
When it comes to performance of methods vs. functions, Mike Ash has some great numbers in his post "Performance Comparisons of Common Operations". Objective-C message send operations are extremely fast, so much so that you'd have to have a really tight computational loop to even see the difference. I think that using functions vs. methods in your approach will come down to the stylistic design issues that others have described.
Optimise the system, not the function calls.
Implement what is easiest to understand and then when the whole system works, profile it and speed up what's slow. I doubt very much that the objective-c runtime overhead of a static class is going to matter one bit to your whole app.
I have class method that returns a list of employees that I can iterate through. What's the best way to return the list? Typically I just return an ArrayList. However, as I understand, interfaces are better suited for this type of action. Which would be the best interface to use? Also, why is it better to return an interface, rather than the implementation (say ArrayList object)? It just seems like a lot more work to me.
Personally, I would use a List<Employee> for creating the list on the backend, and then use IList when you return. When you use interfaces, it gives you the flexability to change the implementation without having to alter who's using your code. If you wanted to stick with an ArrayList, that'd be a non-generic IList.
# Jason
You may as well return IList<> because an array actually implements this interface.
The best way to do something like this would be to return, as you say, a List, preferably using generics, so it would be List<Employee>.
Returning a List rather than an ArrayList means that if later you decide to use, say, a LinkedList, you don't have to change any of the code other than where you create the object to begin with (i.e, the call to "new ArrayList())".
If all you are doing is iterating through the list, you can define a method that returns the list as IEnumerable (for .NET).
By returning the interface that provides just the functionality you need, if some new collection type comes along in the future that is better/faster/a better match for your application, as long as it still implements IEnumerable you can completely rewrite your method, using the new type inside it, without changing any of the code that calls it.
Is there any reason the collection needs to be ordered? Why not simply return an IEnumerable<Employee>? This gives the bare minimum that is required - if you later wanted some other form of storage, like a Bag or Set or Tree or whatnot, your contract would remain intact.
I disagree with the premise that it's better to return an interface. My reason is that you want to maximize the usefulness a given block of code exposes.
With that in mind, an interface works for accepting an item as an argument. If a function parameter calls for an array or an ArrayList, that's the only thing you can pass to it. If a function parameter calls for an IEnumerable it will accept either, as well as a number of other objects. It's more useful
The return value, however, works opposite. When you return an IEnumerable, the only thing you can do is enumerate it. If you have a List handy and return that then code that calls your function can also easily do a number of other things, like get a count.
I stand united with those advising you to get away from the ArrayList, though. Generics are so much better.
An interface is a contract between the implementation and the user of the implementation.
By using an interface, you allow the implementation to change as much as it wants as long as it maintains the contract for the users.
It also allows multiple implementations to use the same interface so that users can reuse code that interacts with the interface.
You don't say what language you're talking about, but in something .NETish, then it's no more work to return an IList than a List or even an ArrayList, though the mere mention of that obsolete class makes me think you're not talking about .NET.
An interface is essentially a contract that a class has certain methods or attributes; programming to an interface rather then a direct implementation allows for more dynamic and manageable code, as you can completely swap out implementations as long as the "contract" is still held.
In the case you describe, passing an interface does not give you a particular advantage, if it were me, I would pass the ArrayList with the generic type, or pass the Array itself: list.toArray()
Actually you shouldn't return a List if thats a framework, at least not without thinking it, the recommended class to use is a Collection. The List class has some performance improvements at the cost of server extendability issues. It's in fact an FXCop rule.
You have the reasoning for that in this article
Return type for your method should be IList<Employee>.
That means that the caller of your method can use anything that IList offers but cannot use things specific to ArrayList. Then if you feel at some point that LinkedList or YourCustomSuperDuperList offers better performance or other advantages you can safely use it within your method and not screw callers of it.
That's roughly interfaces 101. ;-)