Objective C convention: When to use For and when to use With - iphone

According to the Apple guideline , seems it is confusing, e.g. for method viewWithTag
In Java, I would have a method called
getViewByTag // Java version, equivalent to viewWithTag in Obj-C
But I also found there are some method like objectForKey, so why not just use objectWithKey instead?
getObjectByKey or just get // Java version, equivalent to objectForKey,
// but why not objectWithKey? Or not viewForKey above?

I actually think it is much simpler than what most answers think. I think it has less to do with complex programming language specifics, and has more to do with the uniqueness of the object in question.
When you say viewWithTag:, you are asking the UIView for any view that has that tag. There might be several. The UIView will return one of 'em.
However, objectForKey: (to me) sounds like there should be a single object (or nil) associated with that key. So, the key kinda exists and is bound (tightly coupled) to a single object.
EDIT:
There is an answer mentioning the existence of "by", which further implies how the convention has nothing to do with programming language complexities. It's just natural English.
NSString's stringByAppendingString:, for example, uses by, only because the function is written with a the verb appending. You can't say withAppending, that's bad English.

From my observation
While setting/getting the objects, you use WITH.
e.g. For setting of NSMutableArray object
- (id)initWithCapacity:(NSUInteger)numItems
While setting/getting the properties for objects, you use FOR.
e.g.For setting value for property of type NSMutableDictionary
- (void)setValue:(id)value forKey:(NSString *)key
Hope this helps in clearing your doubt

It seems like with is used for properties that directly belongs to an object. A UIView has a tag property so viewWithTag:14 could be rephrased as "Find the view whose tag property is 14".
When you put an object in a dictionary, associated to a key, this key is not necessarily part of the object itself. objectForKey:#"foo" is a way to say "Look for an object that's linked to the key "foo".

The Apple guidelines do not make any such claims as to when to use for or with. The point of the coding convention is to indicate what the types of the arguments may be and to write method signatures which are natural sounding.
The reason for the for or with in the method name is to identify the type or purpose of the first parameter to the method, which helps it read better.
Apple itself uses several conventions but that is the basic purpose, there is no concrete right or wrong just try to identify the first parameter of the method in the method name with either for or with.
And as for Apple conventions - get(whatever) is not even part of the actual conventions, so you could ask when do I use get or not.
Read this http://cocoadevcentral.com/articles/000082.php
also dont forget (by) NSURL urlByAppendingPathComponent etc - get a feel for it and you wont go wrong

You use "with" whenever the parameter is owned or to be owned, or will be a relatively permanent attribute by the object to the left of the "with" word.
initWithCapacity / arrayWithCapacity - the capacity will be an attribute of the container object being called and will be relatively permanent (until you add objects to it beyond the initial capacity)
viewWithTag – return a view "having" the specified "tag" attribute.
Whereas you use "for" to denote a looser association between the "desired" object and a "token" object that you use to get to it.
- objectForKey / attributeForValue – usually the "object" does not own the key.
- documentForWindow – the window is owned by the window controller and not the document. Furthermore there could be more than one window for each document.
But for looser associations of multiple
objects of the same type within a single method call, it's customary that you use something like:
doSomethingForFoo:withThisOtherFoo:havingYetAnotherFoo:
So the order for such complex call is:
for
with
having

Related

Regarding self. in viewDidUnload [duplicate]

This question already has answers here:
When should I use the “self” keyword?
(6 answers)
Closed 9 years ago.
I have an attendant question to iPhone: Why do I need self.<> in viewDidUnload?
Since there is a difference between using self.instance and instance, when is only instance actually used? Just setting the reference to nil seems quite useless? Why is the option there?
Generally, you'll find a lot of useful information here: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html%23//apple_ref/doc/uid/TP40004447-SW4
For the rest of this answer, I'll assume that you are referring to properties automatically synthesised with the #synthesize directive in your .m files.
Executive summary
When you use the form self.property, retain/release is automatically taken care of for you. When you use the form instanceVariable without the self prefix, you're on your own with retain/release.
Longer explanation
When you omit the "self." part, what you really are doing is that you access the automatically generated underlying ivar which the compiler has given the same name as you have given to the property.
If you don't want the compiler to generate ivars of the same name, then you can use an extended form of the #synthesize directive, like this:
#synthesize myvariable=__myvariable;
That way, you will ask the compiler to create an underlying ivar called __myvariable instead of the default myvariable.
Using this extended form, you would refer to either self.myvariable (as a property) or __myvariable (as an instance variable), which can be handy to visually distinguish the two types of access.
With that in place, we can get to the substance of the matter.
When you use self.myvariable, you implicitly call the accessor methods (possibly synthesised for convenience), like this:
self.myvariable = #"Some string";
is equal to
[self setMyvariable: #"Some string"];
or, in the case of a right hand use of the property
myLocalVar = self.myvariable;
is equal to:
myLocalVar = [self myvariable];
The examples above use the accessor names recommended by Apple.
On the other hand, when you use the instance variable directly, you just assign the variables directly without going through the accessors.
Now, one huge advantage of using the accessors on the iPhone is that the automatically synthesised accessors also take care of the retain/release messages, so you don't have to worry about that - or waste code lines handling this somewhat tedious stuff.
Since there is no need to worry about retain/release when you are just reading a property, you could argue that you only need to use the property syntax (with self.) on the left side of an assignment, so whether you want to use the self.-syntax on the right hand side of an assignment is partly a matter of style.
Personally, I have developed a style where I try not to refer to automatically synthesised ivars, unless I have specified them in the #synthesize directive. Otherwise Apple might one day change the way an unspecified #synthesize directive works, and my builds would break. But that is just a personal precaution of mine.
There is one exception to all this, as stated in the docs linked at the top of this answer - and that is that you should not use accessors to the class' own instance variables in the init* methods. One the Mac, you shouldn't use them in the dealloc methods, either, but this is one point where Apple's coding recommendations differ between the two platforms.
Ok, this was a long answer to just say, read the docs, but I hope it clarifies things a little. Memory management in reference counted environments is not trivial, so don't despair if it isn't clear at first.
PS: And if you think this the sort of worries that others should solve for you, log a bug with Apple to ask for garbage collection on iOS. It works nicely on 64-bit OS X.

What's the best NAME for a NAMELESS Category you add at the top of a .m file?

So the other day I was sick of typing out repetetive addTarget:action:forControlEvents:s, and macros are only entertaining for so long, so I did this:
#implementation UIControl (xx)
-(void)addTarget:(id)target action:(SEL)action
{
[self addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
}
#end
and simply added it at the top of the .m file in question.
Works great of course, but notice the "xx".
What's the best thing to NAME a "nameless" Category like this?
Note that it really NEEDS NO NAME as the name will never be used ANYWHERE. The best thing would be to give it no name - but syntactically you cannot leave that blank.
(If you leave the xx blank - it becomes an "Extension" which is quite different.)
I was thinking maybe:
a single underscore
the name of the class again identically
"quick"
perhaps the name of the class in this file (as in "quick extra routines for UIControl in CherryBomb") - so it would be UIControl(CherryBomb), i.e., to remind you that these extra routines are handy for CherryBomb and are indeed in the file CherryBomb.m
"x"
your or your company's initials (use the same "quick" Category name everywhere)
"ThisTextNeverUsedAnywhere"
(By the way ... it appears you do not actually need to include an interface for such a Category, i.e. you can omit...
//you can actually get away without these lines...
//#import <UIKit/UIControl.h>
//#interface UIControl (x)
//-(void)addTarget:(id)target action:(SEL)action;
//#end
... that part and it works fine.)
For people who love Categories, and who doesn't, what's the answer to this troubling question?
What should you name a "nameless" Category where the name is never going to be used again and is irrelevant, because the text is typed directly only in the top of one .m file for use only in that file?
I just use Private. Because they are, well, private... I'd love to hear people's thoughts on that though. :)
An Extension is the same as a Category except the extra methods must go into the same implementation as the original class.
This is useful for adding private methods to a class that don't need to be exposed in the header file, or redeclaring #properties.
Obviously, this can't be used when adding Categories to classes that you don't have the source for. e.g.
UIControl
As for how I name Categories: I use my Three Letter Prefix and the word "Extensions" such as:
UIControl (ADNExtensions)
I like the naming convention "UIControl+MyClassName" for something like that, and naming categories that add to system classes generally as "UIControl+MyPurpose".
If it's a quick, off-the-cuff category, then I'll call it something like DDAdditions. If it's supposed to be a bit more formal, then I'll figure out what the defining purpose of the category is and construct a name off that.
edit more information:
Here's what I do:
When I name the file that contains the category, it is always of the form:
BaseClass+CategoryName.h/m
So if I have a UIButton category called FooBar, the name of the file is UIButton+FooBar.h/m. Seeing this construct in my source tree instantly tells me 2 (potentially 3) things:
That I'm extending a class
What class I'm extending
What the purpose of the extensions is (if the category name is descriptive enough)
If I'm declaring multiple categories in a single file, then the "BaseClass" bit can vary depending on how the extended classes are related.
If there's a mutable-immutable relation (ie, I'm extending both NSArray and NSMutableArray with a category that offers both immutable and mutable variants [ex: -[NSArray shuffledArray] and -[NSMutableArray shuffle]]), then I'll simply use NSArray as the base class.
If there's a kind relation (the things I'm extending are both collections), then I'll try and come up with a base name that reflects that relation, like Collections+CategoryName.h/m.
If I can't come up with a way that the categories are related, then they shouldn't be in the same file. Using a single file for "the categories that just add little things here and there with no defining purpose" is (in my opinion) wrong. File names, like method names, should reflect the purpose of the file.
Coming up with a proper category name takes practice. If I'm in a hurry or am just adding a category to try something out, I'll use "DDAdditions" (my initials + "Additions"). If I'm using a category to hide methods on a class, I'll go with something like "Private" or "Internal".
Otherwise, I find the purpose of these methods and construct a name out of that.
For example, if I'm adding a method to NSDictionary to take its key-value pairs and URL encode them as a query string, then I'll call the category DDURLAdditions or DDURLEncoding or something like that.
The over-arching principle here is to be descriptive. Really it doesn't matter what you call your category or what you name your file as long as its clear what they are. (One of the things we love about Objective-C is that its verbosity makes it largely self-documenting) The only other thing to watch out for is to make sure that your category doesn't have the same name as another category for that same class. (and also that your method names don't conflict, etc)
I can't see anything wrong with _.
The problem with categories is that the compiler and the linker NEED the name of the category to be able to differentiate your symbols or else it can't find the symbols and build your class properly. So call it "Private", or "Additions", or "Convenience" but in any case you'll need a name, and if you happen to have two categories of that type for the same class in different files I advise you to find different names, or better yet: Follow Dave's suggestion.
Note, the name could have been removed for class extension simply because they're only interfaces, it was easy to instruct the compiler to ignore the category name and simply add the methods to the main class block as temporary declaration and thus put a warning inside the #implementation when the methods aren't implemented.
Whereas for a category you needn't to have an #interface matching an #implementation or vice-versa: #interface would contain only declarations that you don't necessarily need to implement (however, don't try to call them if they aren't actually implemented you'll get a crash...). And if you put the #implementation alone without #interface before where you use, the compiler will have stored the method declarations and thus removed the "might not respond to selector" warning.
Note: you can also write an Xcode macro to build your "convenience" category directly...
I prefer categories to be named after what they do. In the example you gave, I would call it "UIControl+Convenience" or "UIControl+Targets". KWTargets or JBTargets is also fine. Most of your examples tell you little or nothing about what the category does, which is confusing when you try to understand unfamiliar code (either because someone else wrote it, or because you haven't looked at it in a while).

How to use id variable in objective-c?

I have an NSArray that contains two types of objects. Lets call them Apple and Orange.
Apple *myApple = [self.searchQueryResults objectAtIndex:indexPath.row];
When I am building my cell's I don't know what type is in my array, apples or oranges. How can I use the generic id type to store the object, and then cast appropriately?
You can use isKindOfClass:(Class)aClass to test the class type:
if ([myObject isKindOfClass:[Apple class]])
// do stuff
I'm not sure why you think you have to cast though. NSArray doesn't care what type of object you store in it, so when you pull it out, it'll still be the same object. But if you want you could still cast by doing something like
Apple *myApple = (Apple *)myObject;
Anyways, knowing the type of class it is should be enough for you to take appropriate action, since it's my understanding that you're showing both types in the same table, all you really need to do is appropriately display their different properties.
Don't mix types of classes in an NSArray.
You can do it, you can run checks for the type - but it's a really bad idea, UNLESS they are both part of the same subclass tree (say, both derivatives of Fruit). Then at least something looking in there can assume what kind of Fruit it might be, and check for particulars.
Basically you will save yourself a lot of headaches if you don't mix types in container classes, when somewhere down the road some bit of code figures for some reason there are only Apples in there but someone throws in a Pear. Then, BOOM!

Couldn't I just pass an copied string to an Core Data property?

The docs say:
The default implementation does not
copy attribute values. If the
attribute value may be mutable and
implements the NSCopying protocol (as
is the case with NSString, for
example), you can copy the value in a
custom accessor to help preserve
encapsulation (for example, in the
case where an instance of
NSMutableString is passed as a value).
So instead of getting into trouble and inconvenience with overwriting accessors in my NSManagedObject subclass, couldn't I simply do something like this?
myManagedObject.firstName = [[firstNameMutableStr copy] autorelease];
This would have the exact same effect, or not? The dynamic implementation would retain that anyways ... so.... why not the easy way?
It's an open question whether having to remember to copy the mutable string every where in code you set the attribute is "the easy way."
With a custom accessor, you just write the copy once then forget about. It copies automatically from that point on.
Just imagine that in thousands of lines of code you forgot to copy just once and developed a subtle bug because that one attribute of the managed object sporadically changed because some other totally unrelated code subsequently changed the mutable string you held only by reference.
I could tell you some stories of weekends lost to debugging because someone took "the easy way."

Do constants always keep the same value?

I've been reading that when conforming to the NSCoding protocol and implementing the methods like -encodeWithCoder:, and encoding objects with i.e.
[coder encodeObject:self.someObject forKey:kSomeConstantToIdentifyFields];
this constant is used to keep track of that object. So later, with help of that constant, the appropriate "field" or whatever can be mapped to that object again (in this case an property).
But: Isn't this funny constant actually a random value when defined like this?
#define kSomeConstantToIdentifyFields #"fieldFooBar"
How does the system manage it to always assign the same value to that constant? Or did I get some stuff about this constants wrong? Is the value actually "fieldFooBar" and not some random number?
The key is a string - a name, if you will - that identifies a field in a dictionary. In this case, the dictionary is what will be written, or read from the archive that was created via the NSCoding protocol.
When you define the key like that, it's not necessarily constant, because it could be changed at some point (but only deliberately, not randomly by the system). As long as you don't change the #"fieldFooBar" string, it'll stay like that throughout the life of the program.
Keys are defined like this, not to be constant, but to be able to flag up compiler warnings and errors, such as spelling mistakes.
If you define the key once, and then refer to it by it's preprocessor symbol, if you mispell it, the compiler will throw an error saying it can't find that symbol. If you just used a string in it's place each time, then the compiler wouldn't know and wouldn't be able to warn you about it. Then you'd be on your own trying to figure out why your field isn't being decoded - because you're asking for the wrong key name.
Before your application compiles, a pre-compilation process occurs. The #define key value directive tells the pre-compiler "whenever you see key, replace it with value". It's not only that they're constants; it's as if you wrote #"fieldFooBar" all over your application yourself.
The reason not to do it yourself is to avoid mistakes, and I think Jasarien gave a great explanation for that in his answer.
Better way to define string constants is to use
static NSString *kSomeConstantToIdentifyFields = #"fieldFooBar";
That would same you some memory. Also, I suppose that isEqual: chects the object pointer, so having all constants point to one place is good.
Do constants always keep the same
value?
I believe that's why they're called constants. ;o)