When do we create memory for ivars in Singleton example by Apple? - objective-c

I have seen the Apple's example of Singleton and couple of other examples.
People say that it is too strict!
But the point is ..even if it is too strict, I want to understand it.
I dont understand that when we call allocWithZone on super, What happens ?
Memory will be created according to super's instance size.
What if our Singleton has ivars ?
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32
I also dont understand that, Why does allocWithZone return the object with a retain call when retain itself is returning the object as it is.

Whenever a method is called in Obj-C it is passed an object reference via the hidden parameter self. For an instance method self refers to the object the method was invoked on, for a class method self refers to the the class object (of type Class) the method was invoked on. Calls to super implicitly pass on self.
Therefore in Apple's example code the call [super allocWithZone:NULL] calls the super implementation of allocWithZone passing the current value of self, which is MyGizmoClass's class object as it is a static method. The implementation of allocWithZone can determine the required memory size from the passed Class object – the details of how are private.
As you've correctly spotted, the call to retain in allocWithZone is pointless but harmless.

Related

Why is -init an instance method and +initialize a class method? [duplicate]

This question already has an answer here:
Why is init not a class method?
(1 answer)
Closed 8 years ago.
In Cocoa, for NSObjects, shouldn't both init and initialize be class methods?
+initialize can be overridden (it's optional) to perform class-wide initialization.
-init performs initialization of a single instance of a class, though it's often refined by adding arguments in classes derived from NSObject (ex: UIView's initWithFrame: method).
Since -init initializes a single instance (in particular, it has access to the instance's variables), it can't be a class method.
From the docs:
The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program.
This means that the first time you send a message to the class, whether it be alloc or some defined class method, initialize is called first, once, for the entire run of the application. As opposed to load, it is possible to include a class in a project and never hit initialize.
init, on the other hand, is
Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated.
Meaning, init is sheerly used for initializing class instances.
Edit --
Following the edited question, alloc creates the instance while init initializes it, which is why alloc is a class method and init is an instance method.

why an accessor method in an ARC environment cannot have a name that begins with 'new'?

this document states that, in order to cooperates with codes written in a MRR(manual retain-release) environment, codes written in an ARC environment cannot have a accessor name that begins with "new", I can't figure out why ARC puts this restriction on method naming.
I believe the cause is because of this:
5.2.1. Semantics of init
Methods in the init family implicitly consume their self parameter and return a retained object. Neither of these properties can be altered through attributes.
A call to an init method with a receiver that is either self (possibly parenthesized or casted) or super is called a delegate init call. It is an error for a delegate init call to be made except from an init method, and excluding blocks within such methods.
As an exception to the usual rule, the variable self is mutable in an init method and has the usual semantics for a __strong variable. However, it is undefined behavior and the program is ill-formed, no diagnostic required, if an init method attempts to use the previous value of self after the completion of a delegate init call. It is conventional, but not required, for an init method to return self.
It is undefined behavior for a program to cause two or more calls to init methods on the same object, except that each init method invocation may perform at most one delegate init call.
Source: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#family.semantics.init
Method names starting with new by convention used to call both the alloc and init methods in the past and I believe there are still methods used in Apple's framwork with the 'new' convention. I guess ARC still takes this into account with regards to memory management.
Also read up on the following: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#family
An Objective-C method may fall into a method family, which is a conventional set of behaviors ascribed to it by the Cocoa conventions.
A method is in a certain method family if:
it has a objc_method_family attribute placing it in that family; or if not that,
it does not have an objc_method_family attribute placing it in a different or no family, and
its selector falls into the corresponding selector family, and
its signature obeys the added restrictions of the method family.
A selector is in a certain selector family if, ignoring any leading underscores, the first component of the selector either consists entirely of the name of the method family or it begins with that name followed by a character other than a lowercase letter. For example, _perform:with: and performWith: would fall into the perform family (if we recognized one), but performing:with would not.
The families and their added restrictions are:
alloc methods must return a retainable object pointer type.
copy methods must return a retainable object pointer type.
mutableCopy methods must return a retainable object pointer type.
new methods must return a retainable object pointer type.
init methods must be instance methods and must return an Objective-C pointer type.
Additionally, a program is ill-formed if it declares or contains a call to an init method whose return type is neither id nor a pointer to a super-class or sub-class of the declaring class (if the method was declared on a class) or the static receiver type of the call (if it was declared on a protocol).
I guess the above means you could call a method something like newobject instead of newObject to avoid the mechanisms of ARC, but that might not make much sense for anyone working with your code. Perhaps you could also avoid the usual memory rules by setting an attribute on your custom new* method that forces some other method family on the property.

What happens when alloc or allocWithZone is called?

I wanted to know , How exactly does an Objective C object gets created. I have been reading different blog posts and apple docs but I could only find incomplete information here and there about ivar and objc_class structures ad various other runtime methods and structures.
But I still did not get, What happens when we call alloc on a Class and how are superclass data members added to the structure ?
If possible, can any one Explain this to me or point me to the source code of these methods that actually allocate memory ?
When alloc is called, it (as any other message send) first gets transformed (by the compiler) into one of the objc_msgSend* functions. This function will get the class structure pointer as its first argument, and #selector(alloc) as its second.
Then, objc_msgSend looks up the corresponding method implementation of +[class alloc], which is, in general, not overridden (custom initialization is conceptually done in -initWith...), so it will generally be +[NSObject alloc]. It is likely that alloc simply calls +[NSObject allocWithZone:]; that function's implementation might do the following steps:
1) It finds the class' istance size (probably via class_getInstanceSize())
2) It allocates memory, most likely using the class_createInstance() function. This function clears the allocated memory to zeroes (that's why, as the specs say, all your ivars are explicitly initialized to 0 on startup), then sets the newliy created object's isa pointer to the class structure itself.
3) The allocWithZone: methods returns the fresh object pointer to alloc
4) alloc returns the object pointer to the sender, most likely it will run into [Class initWith...:].
Hope this helps. Also, apart from the Obj-C runtime docs, don't forget to check the GNUstep NSObject implementations. That's a logic and possible way how the GNU people implemented it and how Apple might have implemented it.
Check out http://www.mikeash.com/pyblog/friday-qa-2009-03-13-intro-to-the-objective-c-runtime.html

Objective-C, ownership and class methods

First off, I'm a Objective-C newbie. :)
I've learned that anything that starts with alloc, new, and copy, gives the caller ownership of the returned object. Does this also apply to class methods? I'm guessing it does, and a recent crash in one of my unit tests seems to confirm it. Apple's Advanced Memory Management Programming Guide doesn't say anything whether there's a difference between class and instance methods.
Update
What I mean that it also applies to class methods is really the "inverse". For instance, NSDecimalNumber has a class method called +decimalNumberWithDecimal:. It seems to return an auto released object (if I release it explicitly, a crash occurs shortly after that). In hindsight, the answer to my question is obvious, as Apple's guide refers to new and alloc as ownership-giving methods, and they're all class methods. Sorry for taking up your valuable time. :)
Also alloc and release. init does not indicate ownership, you are likely mixing that up with alloc. You can memorise it easily with the mnemonic NARC.
If you are naming any class methods init, copy or retain, you should stop that. Those are methods that only make sense in the context of instances. alloc and new are class methods and should only be used in that context. Don't name instance methods alloc or new.
The reason why the guide doesn't say that it applies to both instance methods and class methods is that the methods in question are clearly a mixture of both, so it's obviously the case.
Yes this applies to class methods since alloc and new are class methods which return ownership to the caller. The prefix of copy or mutableCopy should be used for instance methods returning ownership.
Edit For The Update:
You are correct a method like +decimalNumberWithDecimal: is expected to return an autoreleased object, therefore there is no reason to release it. If however they decided to name the method +newNumberWithDecimal: then you would have ownership of the returned object and need to release it. Clang static analyzer will actually complain if you prefix a method with new and return an autoreleased object.
Actually, this is almost correct. alloc, new, and copy give you ownership of the returned object. These are class methods. Other class methods should return an autoreleased object. Instance methods should also return an autoreleased object.
init does not effect ownership and should be use in conjunction with alloc as follows.
[[SomeCoolClass alloc] init]
new is usually the same thing as the above and is sometimes described as "almost deprecated" because it is a throwback to the NeXT days when the allocation and initialization were done in the same step and could not be plot apart as we do today with alloc and init.
Release does not effect ownership, but should only be used on object you already own. Otherwise a crash is likely to occur.
Retain also does not affect ownership, but should only be used on an object you already own. Otherwise the object may not be deallocated when it should be. The result could be a crash, but it can also be very very strange behavior that is difficult to troubleshoot because messages may be sent to the original object that was supposed to have been deallocated instead of a new object pointed to at the same address.

Difference between Obj-C object and instance?

I am learning Objective-C and I don't really understand the difference between an instance and an object. They commonly use both terms. Also, why is the alloc method applied to the class and the init method applied to the object?
An instance is the same as an object, hence why both terms are used and can be used interchangeably — an instance of NSString, or an NSString object.
+alloc is a class method responsible for allocating the memory needed to store a new instance/object, and zeroing-out that memory. It returns a newly created instance/object.
-init, on the other hand, is responsible for further initialising this new instance;1 for example, assigning default values to instance variables. Since -init operates on an existing instance, it’s an instance method.
1In some cases -init might return an instance different from the one created by +alloc.