Assigning autoreleased object to a strong object - ios

Lets say I have a class A with a member variable "myDictionary".
Now if I do this:
myDictionary = [NSDictionary dictionary];
I know that by default members of a class are of strong type. So myDictionary will be available during the lifetime of class A object. Thats what my understanding is about ARC.
But I am getting an EXE_BAC_ACCESS on myDictionary which really confuses me. Do I need to do anything extra in order to avoid EXE_BAD_EXCESS on myDictionary? Because above method returns an autoreleased object.
Thanks in Advance.

If you're not using ARC, then you should use +dictionary any time you
need an autoreleased dictionary, and +alloc/init any time you need a
dictionary that you're going to hold on to (e.g. by placing it in an
ivar), or alternatively if you simply want to avoid autorelease and
-release it manually.
So try to implement like this:
myDictionary = [[NSDictionary alloc] init];

The most likely error here is accessing myDictionary from multiple threads. Ensuring that you always access ivar correctly is one of the several reasons you should always refer to your properties as self.myDictionary rather than directly referring to the _myDictionary ivar. When you need to make this thread-safe, that will ensure there is only one place you need to fix the code.
There are other possible ways to get this error, such as incorrect handling of CFBridging... functions, but the most common is multi-threaded access.

Related

use __weak to local variable in ARC

When you write code like below in ARC
__weak NSMutableArray* array = [[NSMutableArray alloc] init];
The compiler will show you a warning or error and say "Assigning retained object to weak variable. object will be released after assignment".
But if you write like this:
__weak NSMutableArray* array = [NSMutableArray array];
There is no error.
I'm wondering if the second usage is reasonable in some situations? What's the difference between these two codes from memory management perspective? How does it work?
There can be very subtle differences that the compiler cannot know.
Let's take an immutable version: [NSArray array] could return the very same static object every time. So your weak variable will point to a valid object, that has a strong reference somewhere else. Or think of the singleton pattern. On the other hand, when calling alloc/init, convention dictates that you're the only owner of that object, and that will typically leave you with nothing.
Also, the factory method certainly looks more like a (functional) method. In any case, it doesn't communicate ownership of what it returns very well. For an autoreleased object, it's not clear whether you're the the only owner or a shared owner.
They are the same because you lose the object instantly. Compiler cannot know probably, except alloc init, that the object will be lost.
In the first form, the method returns a retained object. ARC ensures, that the object is released when there is no strong reference on the call-site. This is immediately true, with the weak reference - thus, the compiler emits a warning or error.
In the second form, the method returns an unretained object. In this case, the compiler must ensure that the object is still valid across the return boundary. When returning from such a function or method, ARC retains the value at the point of evaluation of the return statement, then leaves all local scopes, and then balances out the retain while ensuring that the value lives across the call boundary. That is, there is a strong reference created by the compiler. This strong reference will be automatically released by the compiler generated code.
Thus, in this case there's no error or warning.
In the worst case, holding that object may require to use an autorelease pool. However the compiler can apply certain optimisations which avoids this. Thus we should not assume that the returned object lives in an auto release pool.
See specification: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#id14
See also this question on SO: Difference between [NSMutableArray array] vs [[NSMutableArray alloc] init]

When to use alloc

Ive tried digging around in old posts, but they were kind of obsolete and years old, so I was concerned things might have changed due to ARC being introduced etc.
Mainly I was looking at some fairly new code that used alloc on an array, which was declared as a property in the header. I was thinking, I don't normally do this and everything is working smoothly. But then came to my mind UIButton and UILabel for example, which has to have alloc invoked, or they won't be added to the view when you want that. Are there any rough guidelines for when its actually needed. I would think any object needs this, but the array vs. button/label thing as I just described made me wonder what is the reasoning behind this.
Thanks in advance
This is 100% dependent on the actual objects being used from the framework. The really great news, though, is that Apple is extremely consistent. If you send a message that contains an "Alloc" in it anywhere, you are responsible for making sure that it has been released.
Here's a super document on it from Apple.
You use alloc always if you create the object on your own.
Which means that sending alloc is normally followed by an init method.
It might sometimes look like it's not always the case, as many classes have convenient constructors that return an already allocated and initialized object to you.
But there is still alloc and init called to create the object.
It's just done for you by the system.
But the difference between convenient constructors and manually creating objects isn't new to ARC, it has always been around.
Example for creating an NSArray on your own:
[[NSArray alloc]initWithObjects:#"Test", nil];
and as NSArray has an convenient constructor here the example for that:
[NSArray arrayWithObjects:#"Test", nil];
If you use ARC, there is no real difference.
Without ARC, the object returned by the convenient constructor would still be autoreleased, while the manually allocated object has to be released by you at a later point (or you have to add an autorelease after the init).
So the main difference is the owner ship:
In the manually created example the object belongs to you, so you are responsible to clean up after you don't need it anymore.
If something is declared in .xib then it is automatically allocated for you. Just use it. While If you are creating a view in code u must alloc it first. And if you have a property NSArray/NSMutableArray etc, u might be doing one of the following:
_array = [NSArray new];
_array = [[NSArray alloc] init];
_array = [NSArray arrayWithObjects: values count:2];
_array = # ["ABC", "xyz"];
etc,
so you are actually allocating it if you are using any of these methods.
I do not really understand, what
they won't be added to the view when you want that.
means, but here is the story:
Every object is allocated using +alloc. To be honest, it is +allocWithZone:, but this does not have any meaning at this place.
The very first message you have to send to the newly created instance object (remember: you sent +alloc to the class object) is an initialization message, something like init…. To put this together you will find code as:
… [[TheClass alloc] init…] …;
Because it is boring typing there are new allocators. They put this messages into one:
… [TheClass new…] …;
(This has some advantages for the class implementor, too, but this is transparent to you. Think of it as sending +alloc, -init….)
In earlier times it has been a good idea to send an autorelease message to it as the next step for some reasons:
… [[[TheClass alloc] init…] autorelease] …;
This has been put together to convenience allocators:
… [TheClass theClass…] …
This is what you find most of the time when reading old code. Using ARC you do not need convenience allocators anymore: There is no autorelease. So there is no reason for convenience allocators anymore. But we had MRR for years and there are still many convenience allocators. (Now called factory methods, but CA's are only a subset of these. A subset you do not have to care about. It's all gone with ARC.) Because there are that many CA's, one still uses them. (And there is a performance issue with them. In nowadays I only write new allocators, which has the advantages of a CA, but not the disadvantage of autorelease.)
To make a long story short: You simply do not see sometimes that +alloc is used.

Why the alloc and the init may return the different object when creating the new object?

As the ios's document says that we should creating a new object following
NSObject *newObject = [[NSObject alloc] init];
And never create a object like this
NSObject *someObject = [NSObject alloc];
[someObject init];
It says that the init may possible return the different than alloc,so I'm confused that why or in what case they return the different object?Thanks!
This behavior is allowed so that your class could produce a stand-in object for the one being created. You may want to do that for several reasons:
Object Caching - If you need to create and release the same objects often, for example, when you create wrapper objects for numeric values, you could store object instances for reuse, and return them when requested. If you make your objects immutable, you could save significant amounts of memory by sharing your objects.
Returning a subclass - There are multiple design reasons for doing this, for example, to implement hidden functionality that is compatible with the interface of the object being returned, such as copy-on-write.
Returning nil - You are allowed to do this to indicate failure of your init function.
Take as an example the huge number of initWith... methods of the NSString class. Some are very specialised, and would like to return a specialised object. alloc cannot know that. So [NSString alloc] returns a generic NSString object, and each initWith method can return some specialised object instead.
Because
NSObject *someObject = [NSObject alloc];
All alloc does is allocate memory for the object. At this point in time there is no actual NSObject type, just a region of memory. This doesn't have any direct consequence if you immediately call init but you might fail to realize the init wasn't called and attempt to use the object without initialization.
The other answer has an even better reason, you might not get the same object back from init.

IOS: Do i need to retain key in dictionary ios?

I have dictionary in which i m storing
1)keys = which is string attribute of an "SimpleObject" with 'assign' property
--2) value = "SimpleObject"
NSMutableDictionary retains the object so im releasing the object. the key is present in the same object. The key is string.
Now do i need to explicitly retain the string key before add it to dict ?
No, you do not need to explicitly retain the NSString, because your object already does that. Since the dictionary retains the object, the NSString is safe from being released prematurely.
Moreover, NSDictionary makes a copy of your string key, as a precaution against using a mutable object as a dictionary key (which is very bad). That's why you are free to change that key inside the object as you please. Of course that would not change the placement of the object inside the dictionary.
The answer is no. Whether or not you are using ARC. No.
No, you do not need to retain the keys (or the values) of an NSDictionary. This is because NSDictionary copies the key. When you retrieve an objects with objectForKey: isEqual: is used to determine which key refers to the object you passed in.
The basic rule in manual memory management in Cocoa is -- worry about what you're doing in that object or method; don't worry about what any other object is doing.
All you're doing is passing the key to a method of the dictionary. You are not storing it around anywhere. Whatever the dictionary does with it, it is responsible for the proper memory management. What it does is none of your business.
(There is a slight exception with blocks, in that you sometimes must copy them before passing to a type-agnostic method. But let's not worry about this for now.)

Accessing obj as property vs method param (style preferences)

When it comes to accessing objects from different methods in the same class, from what I understand, these are two ways to do it. Given that I DO want to hold a property pointer to this object, which is the better way to go about this? I've been thinking about this for a while, and wondered if there is a preference consensus.
#1:
NSArray *array = ... // Get array from somewhere
self.myArray = array;
[self doSomethingToMyArray];
This method takes no parameter and accesses the array via its own property via self
- (void)doSomethingToMyArray
{
// Do stuff with/to the array via self.myArray
[self.myArray ...];
}
Vs #2:
NSArray *array = ... // Get array from somewhere
self.myArray = array;
[self doSomething:array];
This method takes an array and accesses the array via its own method parameter
- (void)doSomething:(NSArray *)array
{
// Do stuff with/to the array via method parameter "array"
[array ...];
}
I think it's primarily going to depend on what doSomethingToMyArray does and who calls it.
Fairly obvious comments:
if you want to do that to more than one array, you need to take an argument;
if what you're doing is actually logically more to do with the array than with your class (e.g. you've implemented randomisation of the order of the array) then it'd be better as a category on NSArray rather than being anywhere in that class at all;
if there's any possibility of subclasses wanting to redefine the manner in which the array is obtained then you'll want to invoke the getter somewhere;
similar concerns apply if a subclass or an external actor should be able to intercede anywhere else in the process.
Beyond those concerns there are a bunch of us that just prefer this stuff to be functional anyway — noting that you're doing something to the array, not with the array, in which case you'd tend more towards self.myArray = [self processedFormOf:array] (or self.myArray = [array arrayByDoingSomething]; if the category tip makes sense).
So, ummm, I don't think there's a clear-cut answer.
That depends on what you want to do, just by reading it:
doSomething:array
I would assume the above method takes ANY array and performs an action, whereas:
doSomethingToMyArray
with this method you are describing the intention of doing something to your instance's array. Inside this method (given that you followed Apple good coding practices and you synthesized your property to _myArray) , you could either go with:
[self.myArray message]
or preferably
[_myArray message]
Your second option is sort of silly. If you're storing a pointer in an instance, then it's so that you can use it later (within that instance) without needing to pass it around whenever you call a method.
This is also dependent on whether you're using ARC or not (use ARC if this is a new project). In a non-ARC project, self.myArray = foo; will do a very different thing than myArray = foo; (the self. syntax calls a property, which in many cases will correctly retain the thing you've assigned). In an ARC project, they'll generally have the same behavior, and there's less room for error.
Personally, in my ARC projects, I do not use the self. syntax from within a class, since it's just extra typing for the same effect. This ties in nicely with the new usage of #property, where you're no longer required to write a #synthesize block, and Objective-C will automatically generate an ivar for you, with the name of your property prefixed by an underscore, i.e. _myPropertyName. That makes it very clear visually when you're accessing code from outside the class (crossing the encapsulation boundary), where things will look like foo.bar = baz; versus inside the class, where it's just _bar = baz;.
IMHO, clearly, a function call would incur an extra overhead.
you would have to allocate an object pointer (though minimal) over the stack (extra memory)
Have to pass it (extra processing)
Property is actually a small function call unless you have made customizations to the getter. I also assume that compiler may have its own optimizations put in place for such accessors so that you can access them with minimal overhead, though I do not have any source to cite this.

Resources