In most languages I have dealt with, one something is called a convenience method, it means that the method does some small task that gets done very frequently, and therefore it is more convenient to use said method.
In Objective-C does this definition hold true? Or is it generally only used to describe class methods that return a prebuilt object? ex. [NSString stringWithContentsOfFile:...]
Is this just a preference thing, or are there some hard and fast definition for these terms?
Cheers,
Stefan
What you are talking about is actually more specifically a "convenience constructor" in Objective C. (Note that it's not really a constructor in the C++/Java/C# sense, it's actually an object initializer/factory method, but it seems to be the convention to call the "convenience constructors"). "Convenience constructors" in Obj C are a convention or pattern for creating a constructor/initializer/factory method for a class which takes specific parameters. This pattern also has some special conventions that you should follow (such as autoreleasing the new object within the constructor), so that your custom classes fit in well with the built-in types.
See this page (a little way down) for more info: http://macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=3
As for "convenience method," this specific term doesn't have any special meaning in Objective C. You can create any type of convenience method in Obj C, and there is no expectation about what it should or should not do. It's only "convenience constructor" that has a special meaning.
So far as I know, "convenience method" means basically what you defined it to mean here: a single method or function which replaces a more complicated series of invocations because of its frequency of use.
In Objective-C, the "ordinary" way to create a new instance is something along the lines of NSSomething * mySomething = [[[NSSomething alloc] initWithParam:... andParam:...] autorelease]. Many classes provide convenience constructors which simplify these three steps (in fact, in most cases, they probably literally do exactly the same thing, but wrapped behind a class method call).
Related
I'm new to Objective-C and was wondering if anyone could provide any information to clarify this for me. My (possibly wrong) understanding of object instantiation in other languages is that the object will get it's own copies of instance variables as well as instance methods, but I'm noticing that all the literature I've read thus far about Objective-C seems to indicate that the object only gets copies of instance variables, and that even when calling an instance method, program control reverts back to the original method defined inside the class itself. For example, this page from Apple's developer site shows program flow diagrams that suggest this:
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW1
Also in Kochan's "Programming in Objective-C", 6th ed., pg. 41, referring to an example fraction class and object, the author states that:
"The first message sends the setNumerator: message to myFraction...control is then sent to the setNumerator: method you defined for your Fraction class...Objective-C...knows that it's the method from this class to use because it knows that myFraction is an object from the Fraction class"
On pg. 42, he continues:
"When you allocate a new object...enough space is reserved in memory to store the object's data, which includes space for its instance variables, plus a little more..."
All of this would seem to indicate to me that there is only ever one copy of any method, the original method defined within the class, and when calling an instance method, Objective-C simply passes control to that original copy and temporarily "wires it" to the called object's instance variables. I know I may not be using the right terminology, but is this correct? It seems logical as creating multiple copies of the same methods would be a waste of memory, but this is causing me to rethink my entire understanding of object instantiation. Any input would be greatly appreciated! Thank you.
Your reasoning is correct. The instance methods are shared by all instances of a class. The reason is, as you suspect, that doing it the other way would be a massive waste of memory.
The temporary wiring you speak of is that each method has an additional hidden parameter passed to it: a pointer to the calling object. Since that gives the method access to the calling object, then it can easily access all of the necessary instance variables and all is well. Note that any static variable exists in only a single instance as well and if you are not aware of that, unexpected things can happen. However, regular local variables are not shared and are recreated for each call of a method.
Apple's documention on the topic is very good so have a look for more info.
Just think of a method as a set of instructions. There is no reason to have a copy of the same method for each object. I think you may be mistaken about other languages as well. Methods are associated with the class, not individual objects.
Yes, your thinking is more or less right (although it's simpler than that: behind the scenes in most such languages methods don't need to be "wired" to anything, they just take an extra parameter for self and insert struct lookups before references to instance variables).
What might be confusing you is that not all languages work this way, in their implementations and semantically. Object-oriented languages are (very roughly) divided into two camps: class-based, like Objective-C; and prototype-based, like Javascript. In the second camp of languages, a method or procedure really is an object in its own right and can often be assigned directly to an object's instance variables as well - there are no classes to lookup methods from, only objects and other objects, all with the same first-class status (this is an oversimplification, good languages still allow for sharing and efficiency).
The compiler seems to be happy, I'm happy with slightly improved readability, but Xcode's code completion doesn't particularly recognize alloc and class when invoked this way:
MyClass* object = [MyClass.alloc initWithBounty:bounty];
<...>
if ([object isKindOfClass:MyClass.class])
<...>
So I was wondering what is wrong with the above, if at all?
Well, primarily what's wrong is that dot notation is for retrieving things that are conceptually properties. alloc does not access a property of the class; it creates an object. Using it for any zero-argument method is not more readable — it's confusing.
MyClass.class is actually not problematic in that way, but there's no way to declare properties on a class and they usually aren't thought of as having properties, so the autocomplete apparently doesn't support it.
Dot notation is originally added to be used for property access. So you can use them only for
A method takes no parameter and returns single value (getter).
A method takes single parameter and returns no value (setter).
Otherwise, recent compiler will complain about it.
Anyway, I agree to #nhgrif that using dot notation on non-property method is not a good practice.
I went through the source code of GNUStep's NSNumber's implementation to understand how does factory method implementation works there.
From there What I could understand was we have NSNumber with blank implementation for all initWithXYZ kind of methods. and NSTemporaryNumber was acting like an intermediate class in the hierarchy that implemented all the initWithXYZ methods where it actually created objects of specific types , autoreleased itself and returned the created object.
Also allocWithZone was overridden to avoid creation of NSNumber object and to create object of NSTemporaryNumber if it was so otherwise create objects of specific types.
What I didn't understand was, can't the same things be done by NSNumber itself ?
why give blank implementations at all , create the object of specific type and then autorelease self.
Also if we have implementations of createXYZ methods in NSNumber itself, why have initWithXYZ methods ?
If I have to implement a factory implementation for my project where say I have two mediaItems, video , audio and photo etc.
for which I have separate classes and corresponding enums which I pass to initWithMediaType who will create an object of correct child class, return it and destroy itself.
Have two classes like NSNumber and NSTemporaryNumber: say Media and TemporaryMedia, one with blank implementations other with implementations as mentioned above ?
Should I do something like this ?
Is this the way we have to implement Factory pattern in Objective C ?
My question might seem silly biut I come from a Java, C++ background where things looked different.
The purpose might be the same but I am finding it difficult to understand the way Objective C does it since it does not have abstract classes.
Link to the source:
http://www.koders.com/objectivec/fid46956186C20201706AFE1744AA7AFEEE09D1FE5A.aspx
The point is that NSNumber is a class cluster. The class you actually end up with may be an NSIntNumber, an NSFloatNumber or one of several others. They all respond to the same messages as NSNumber (and, usually in this pattern will be subclasses of it, but that isn't required) so it makes no real difference to the caller.
When you call alloc there's no way to know what sort of object to create, so a neutral type is created and returned instead. It substitutes appropriately upon receiving an appropriate init.
So this pattern is for the implementation of class clusters. You can ignore it if writing a class that provides only instances of itself.
I was reading Apple's documentation, The Objective-C Programming Language (PDF link). On pg. 18, under The Receiver’s Instance Variables, I saw this.
A method has automatic access to the receiving object’s instance
variables. You don’t need to pass them to the method as parameters.
For example, the primaryColor method illustrated above takes no
parameters, yet it can find the primary color for otherRect and return
it. Every method assumes the receiver and its instance variables,
without having to declare them as parameters.
This convention simplifies Objective-C source code. It also supports
the way object-oriented programmers think about objects and messages.
Messages are sent to receivers much as letters are delivered to your
home. Message parameters bring information from the outside to the
receiver; they don’t need to bring the receiver to itself.
I am trying to better understand what they are describing; is this like Python's self parameter, or style?
Objective-C is a strict superset of C.
So Objective-C methods are "just" function pointers, and instances are "just" C structs.
A method has two hidden parameters. The first one is self(the current instance), the second _cmd (the method's selector).
But what the documentation is describing in page 18 is the access to the class instance variables from a method.
It just says a method of a class can access the instance variables of that class.
It's pretty basic from an object-oriented perspective, but not from a C perspective.
It also say that you can't access instance variables from another class instance, unless they are public.
While I would not say that it is a "slam" against Python, it is most certainly referring to the Python style of Object Orientation (which, in honesty, is derived from the "pseudo-object orientation" available in C (whether it is truly OO or not is a debate for another forum)).
It is good to remember that Python has a very different concept of scope from the rest of the world — each method more or less exists in its own little reality. This is contrasted with more "self-aware" languages which either have a "this" variable or an implicit instance construct of some form.
While reading the documentation, I wonder if objc_msgSend() is actually the "core technology" in delivering the functionality for making Objective-C "object oriented". Maybe someone can explain in more detail which other pieces come into place to enable the object oriented paradigm of Objective-C?
Not entirely.
Objective-C is object oriented solely because it encapsulates data and functionality into a single container; a class.
That is pretty much all there is to "object oriented programming".
Now, there are many different kinds of object oriented programming and one critical aspect is whether or not a language uses dynamic or static dispatch.
In a statically dispatched language -- C++ is the best example (yes, I know it has virtual methods that give a form of dynamic dispatch) -- a method call is wired up at compile time and cannot change at runtime. That is, the implementation of the method that will be used to fulfill the method call is fixed during compilation and cannot change at runtime.
With a dynamically dispatched language like Objective-C, the implementation of the method that will be used to fulfill a method call is determined each time the method call happens. Thus, through the use of categories or the runtime's API, it is possible to change a method's implementation while an application is running (this is actually how Key Value Observation works, for example).
objc_msgSend() is the hook that does the dynamic dispatch. It takes a reference to an object or a class & a method name -- a selector or SEL, as it is called -- and looks up the implementation on the object or class that goes by that method name. Once the implementation is found, it is called.
If no implementation is found, objc_msgSend() will then take a series of steps to see if the class or instance wants to handle the unrecognized method call somehow, allowing one object to stand in for another (proxying) or similar functionality.
There is a lot more to it than that. I would suggest you read Apple's documentation for more information.
There's quite a bit more to it.