Objective-C 101 (Retain VS Assign) Nsstring

NSString property: copy or retain?

For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your @property declaration. Specifying retain is something you almost never want in such a situation.

Here's why you want to do that:

NSMutableString *someName = [NSMutableString stringWithString:@"Chris"];

Person *p = [[[Person alloc] init] autorelease];
p.name = someName;

[someName setString:@"Debajit"];

The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be @"Debajit" if the property is marked retain, but @"Chris" if the property is marked copy.

Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using @synthesize you should remember to actually use copy instead of retain in it.)

Should I use retain for a NSString to be output via a reference to a NSString pointer?

TL;DR

Do not return owned object values by reference.

Explanation:

By convention, objects returned by reference (or even by value) are not owned unless the method specifically states this. If the method name contains copy or new then it is expected to provide an owned reference, otherwise the reference count is considered to be irrelevant.

For instance, Cocoa methods that return an NSError by reference return an autoreleased NSError which you are not expected to release.

What this means is, you can do either, as long as you indicate what you are doing via the method name. You probably just want to return an autoreleased reference and let the caller decide whether they want to keep holding on to it or not.

Apparently, Apple feels you should not return owned values by reference, according to this document:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

When should i use assign in Objective c?

You should assign things that aren't objects. Any C type (such as int, float, char, double, struct, and enum) should be assigned.

What is the difference between copy and retain?

In a general setting, retaining an object will increase its retain count by one. This will help keep the object in memory and prevent it from being blown away. What this means is that if you only hold a retained version of it, you share that copy with whomever passed it to you.

Copying an object, however you do it, should create another object with duplicate values. Think of this as a clone. You do NOT share the clone with whomever passed it to you.

When dealing with NSStrings in particular, you may not be able to assume that whoever is giving you an NSString is truly giving you an NSString. Someone could be handing you a subclass (NSMutableString, in this case) which means that they could potentially modify the values under the covers. If your application depends on the value passed in, and someone changes it on you, you can run into trouble.

Objective-C with ARC: Custom setter does not retain

This looks like a bug to me; your code should be fine. If you haven't yet done so, file a bug at http:// bugreport.apple.com, and attach your sample project.

Edit: On further examination of your sample project, this is not a bug.

The overreleased object in your sample project is not the NSDate instance. You can comment out the tc.date = now call in your sample project entirely, and you'll still see the same crash. In fact, you can take out the NSDate stuff entirely. The over-released object is actually the TestVC object itself.

Here's what's happening.

In iOS 4.0, UIWindow got a rootViewController property. Where previously you would just call [self.window addSubview:myRootcontroller.view] upon launching the app, this change now meant that the window would actually have a reference to the root view controller. This is important for the sake of passing on rotation notifications, etc. In the past, I believe UIWindow would automatically try to set the rootViewController when the first subview was added (if it was not already set), but in your sample project that is clearly not happening. That may be due to the way you're creating the view, or may be due to a change in iOS 5.0. Either way, it wasn't ever documented behavior, so you can't rely on it happening.

In most cases, your app delegate will have an ivar pointing to the root view controller. It's not strictly required, but it's usually what happens. However, in the sample project you presented, the view controller is not owned by the app delegate. Nor did you set it as the window's root view controller. As a result, at the end of the -application:didFinishLaunchingWithOptions: method, there is nothing left with a strong reference to the view controller. Your app delegate isn't holding on to it, and the window itself isn't holding on to it. As such, ARC treats it as a local variable (which it is), and releases it at the end of the method.

Of course, that doesn't the change the fact that your UIButton still has an action method targeted at your controller. But as noted in the documentation, -addTarget:action:forControlEvents: does not retain the target. So the UIButton has a dangling reference to your view controller, which has now been deallocated since nobody has a strong reference to it. Hence the crash.

The fix for this is to change this line in your app delegate:

[self.window addSubview:tc.view];

to this:

self.window.rootViewController = tc;

With that single change, everything now works just fine.

Edit: Also make sure the "Precheck code for ARC migration" setting is not on, as this would cause the compiler to treat the code as manually managed, and this would not insert the proper retain/release calls.

Which attribute to use as property for class

Since it's a pointer to a class object, and class objects live for the lifetime of the app, memory management actions like retain and release have no effect on it. So it shouldn't matter whether you use assign or release. It would be simpler to use assign.

Are @property(nonatomic)ivar @property(nonatomic,assign)ivar the same or different?

As stated in the docs:

assign -
Specifies that the setter uses simple assignment. This attribute is the default.

So no, as far as I know they are the same.



Related Topics



Leave a reply



Submit