When should i use assign in Objective c? - iphone

I understand the reason i should use retain, but why should I ever use assign? (besides to avoid retain cycles)
[EDIT]
So if i understand Chuck's answer on https://stackoverflow.com/questions... correctly, when ever I use assign, the variable would lose scope once it gets out of scope of the method just like it does in regular C-type language behavior?

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

Few examples I can think of:
It is not an object. Such as BOOL, int
Most of the times delegate properties are assigned (to prevent cycles)

Anything that is not an object
Delegates
IBOutlets that are not top level (i.e. subviews since those are already retained by the view)

Assuming that Chuck's answer from the linked question is correct, there's not really a "scope" in Objective-C. Sounds like you should just use assign for any primitives, like ints or BOOLs. Anything that you need to have ownership of, use retain (or other commands, as Chuck describes).

Related

When to use #property? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should I use #properties?
When to use properties in objective C?
I have been programming in objective-c for a little over a year now, and I always felt like it was a convention to use #property and #synthesize. But what purpose do they really serve ? Are they solely there to be communicated between classes ? So, for instance, if I use an NSMutableDictionary only in the scope of the class where it was declared, an omission is O.K. ?
Another question:
If I set the property of an NSMutableDictionary, it is retained, right ? So, in my class I don't have to call alloc() and init(), do I ?
What are the rules to use properties ?
But what purpose do they really serve?
Access control to iVars and abstraction between representation and underlying data.
Are they solely there to be communicated between classes?
No, they are for when you want to control access to iVars instead of accessing them directly or when you could in the future change underlying data structures but wish to keep the current representation.
So, for instance, if I use an NSMutableDictionary only in the scope of the class where it was declared, an omission is O.K.?
It depends. Do you want to have controlled access to the iVar? Would it be possible for your code to change so the dictionary is fetched and not a direct iVar. Usually, the answer is yes.
If I set the property of an NSMutableDictionary, it is retained, right?
Depends on how you declare the property.
So, in my class I don't have to call alloc() and init(), do I?
You have sloppy wording here. I think you are asking if you still need to construct an instance of a property. Yes, you will need to construct an instance of a property in some way. There are lots of ways of doing this.
NOTE: the convention for talking about methods is use their signature. Instead of alloc(), you would use -alloc.
What are the rules to use properties?
This you will need to read the doc for.
Like in another languages, when we want to make our variable global or public we use public access modifier. In objective c when we want access our another class variable in other class, we use #property and #synthesize them. Basically #synthesize is way by which compiler create a setter and getter methods for that variable. You can manually create them but not use #synthesize.
By creating object of that class you can access your property variable in other class.
By using retain, you clear that is take place memory and not exist until that container class not goes dispose or released.
Properties simply make your life easier.
Nowadays use properties as much as you can in terms of memory management, code-style and timesaving.
What do #propertys do?
They can create getter and setter methods (depends on given parameters).
Normally you declare instance variables in the header file (like in c++).
Now you simply let that be and instead of that declare the properties you want for instance variables.
Properties can get multiple arguments.
For normal objective-c objects, where you need a pointer (*) you would write.
#property (nonatomic,retain,...)
When you #synthesize it it creates a getter and a setter.
The setter automatically does stuff like releasing your old object, that your variable hold and retaining the new one.
So you don't have to do that manually (which should be quite often the case). Thats important.
You also can give it arguments (readonly,readwrite) to decide if to set a setter or not.
You can even declare a #property in the header file readonly and override that in your implementation file with a extension (a category with no name).
To dive deeper into this, read the apple developer manuals, which are quite effective.
Hope that helps a bit.
Shure it is the tip of the iceberg, but it's mostly everything you need.

does objective-c methods support "pass by value"?

Does objective-c methods support "pass by value"? Or perhaps to be more specific:
Is the default behavior for parameters passed into a method pass-by-reference?
If yes, are there any variations from this in some circumstances - for example if the parameter is just a basic int as opposed to an object? (or is this not relevant in objective-c)
Is there anyway to have a method support pass-by-value for a basic variable such as int?
Is there anyway to have a method support pass-by-value for an object? (I'm assuming no here, but for completeness will ask. Of course one could within the message do the copy yourself, however for this approach I'll consider this not to be something objective-c methods offers you, i.e. rather it was a do-it-yourself)
thanks
Objective-C does not support references, at least not in the C++ sense of the term.
All Objective-C objects are allocated on the heap, and therefore all "object variables" must in fact be pointer types. Whether a pointer can be considered to be effectively the equivalent of a reference is open to debate. When talking C++ for example, there are clear semantic differences (otherwise, what's the point...)
So to answer your questions:
No, Objective-C only supports pass-by-value. If you pass an object pointer to a method, you pass the pointer by value - you are not passing a reference.
There is no inherent difference between objects and primitives in this regard, apart from the fact that objects are always referred to by pointer, never by value. You can pass a primitive type pointer in if you like.
Yes. This is always the case. Again, if you pass in a pointer to a primitive, you are passing a pointer by value, not a reference.
You're pretty much bang on the mark with this one, other than the fact that you're passing around pointers, not references.
No. It's pass-by-value by default, like in C. Except for the fact that for the Objective C class instance references, the value is a reference. So Objective C class instances are passed effectively by reference.
N/A
See 1.
Not really. You can serialize, pass the string, and recreate inside. Or you can have the object store its ivars as a structure and pass that structure by value. Some objects support cloning.

When do i need assign property and when not?

Can any one give me example when do i need assign property only...??
Primitives: int, float, structs, etc.
Pointers to "non-objects": c arrays, functions.
Helper properties that you intend to retain in other controller objects. Delegates and handlers are common throughout.
Otherwise, refer to the memory management docs here. Pay special attention to the section on retain cycles.
http://developer.apple.com/iphone/library/iPad/index.html#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html
Every time you do not want to retain it.

Would I ever want to use any #property attributes other than "retain" and "nonatomic" for UI variables?

I'm diving into iOS development and I find that for each of my UI controls, I always just blindly declare their #property like so, since that's how it was done in some tutorial I read when I started learning...
#property (retain, nonatomic) IBOutlet UILabel *lblStatus;
I'm still getting familiar with these attribute types and what they mean, but I find these two attributes allow me to accomplish my goals. Would I ever want to use any #property attributes other than "retain" and "nonatomic" for UI variables?
Thanks in advance for all your help!
NOTE: This answer is more relevant to UI Items in general.
Yes there is other situation where you would want to use the "assign" macro instead of "retain" (Assign is default for now but you get warning at compile-time if you don't specify it explicitly)
Apple gives a good example of this on one of their tutorial: Advanced UITableViewCell
They only "assign" in order to avoid cycle retains. (each of the view retains the other so they can't be deallocated).
NOTE: I missed the reference to UI variables in the question, so this answer is a more general discussion.
Yes, you will definitely need to use other attributes than those two, although that combination is the most common one.
copy - Use this in situations where you don't want as subsequent change to the data to be "picked up" by your class. In other words, when you want full control of the data once it's passed in. Sometimes this is desirable, sometimes not. Classes like NSString and UIColor are often used through properties with the copy attribute. My answer here gives a little bit more background.
assign - You use this with primitive types like int. You can't retain or copy an int or a float, because they are not objects, so you have to use assign. (Also, you don't have to, and can't, release those variables in your dealloc method.) This is true also for C structs, which are not covered by the Objective-C retain count system.
assign special case - sometimes you use assign even with objects, because you want to avoid retain cycles. Look at the header for UITableViewfor example. You'll notice that the delegate property is declared like this: #property(nonatomic, assign) id<UITableViewDelegate> delegate . Delegate properties should always be declared with assign and the same applies in some other situations, although you are not likely to run into them very soon.
nonatomic - This tells the compiler that the property is intended only to be accessed from one thread, and therefore it can omit some code that would otherwise slow down your program (potentially considerably). So the rule here is: if the property will, or might, be accessed from several threads, you should not declare it to be nonatomic (atomic is the default). Note however that making properties atomic is in no way sufficient to make your code thread safe. That's another, and much much thornier, topic.
The answer is NO. The reason behind this is the reason why we are using nonatomic and retain. From memory management guide "Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, UIKit reestablishes connections between the objects using setValue:forKey:, which uses the available setter method or retains the object by default if no setter method is available. This means that (assuming you follow the pattern shown in “Outlets”) any object for which you have an outlet remains valid." So we are providing this setter just to make a match with the default behavior. Yes, it is possible to declare the setter in other ways but at least I have not found no reason to do so. If we use assign instead of retain, then there is no guarantee that the objects will remain valid. And memory management is already critical in iPhone and obviously I don't want to make it further critical by ignoring the convention. -- edit The answer NO is only for UI variables, that is for IBOutlets. Don't be confused. Other attributes are necessary in other cases as explained in other answers.
(retain) is generally used for instance variables and assign will go for delegates and primitive data types like bool , int

Is an object in objective-c EVER created without going through alloc?

I know that there are functions in the objective-c runtime that allow you to create objects directly, such as class_createInstance. What I would like to know is if anything actually uses these functions other than the root classes' (NSObject) alloc method. I think things like KVC bindings might, but those aren't present on the iPhone OS (to my knowledge, correct me if I'm wrong), so is there anything that would do this?
In case you're wondering/it matters, I'm looking to allocate the size of an instance in a way that circumvents the objc runtime by declaring no ivars on a class, but overriding the +alloc method and calling class_createInstance(self, numberofbytesofmyivars).
Thanks
EDIT
I think I need to be more specific. I am adding classes to the runtime at runtime, and possibly unload and reload an altered version of the same class. I've worked around most of the issues so far, due to things like class_addMethod, but there's no equivalent for ivars after the class has been registered. The two solutions I can think of are having no actual ivars as far as the runtime is concerned, but overriding alloc to make sure I have enough room for them through extraBytes, or alternatively declaring an ivar which is a pointer to all of my actual ivars, which I can then obviously do whatever I want with. I would prefer to use the former strategy but there are a number of things that can go wrong, like if something allocates an instance of my object without going through my overloaded alloc method. Does anyone know of one of these things?
I'm not sure if you're trying to change the behavior of existing classes, which is not safe, or trying to do something for custom classes you own that are direct subclasses of NSObject, which probably is.
Almost all NSStrings you see in practice are instances of a private subclass, and that subclass allocates space for the string inline with the object. Like, instead of containing a pointer to a char*, the character data comes right after the ivars in the object. The extraBytes parameter in NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone) is there for purposes such as this.
So on the one hand, yes, you can pull tricks like that. On the other, you need to know you're doing it with your stuff. If you try to do something like that with the private subclass of NSString (which is private, so you're only going to interact with through runtime introspection), you're probably going to conflict.
There are a few public cocoa classes that also do stuff like this, so you're best off if your classes inherit directly from NSObject. NSLock is one. The layout in memory for a custom subclass of NSLock looks like { isa, <ivars of NSLock> <ivars of subclass of NSLock> <more NSLock stuff, space reserved using the extraBytes parameter> }.
Also, just for the heck of it, note that +alloc calls +allocWithZone:, and +allocWithZone: is the more common override point.
I'm not sure why you'd want to do what you're suggesting--I don't see any reason you couldn't do it, but according to this post, there's usually no reason to use class_createInstance directly (I don't know of anything that uses it specifically). class_createInstance also doesn't take into account memory zones or other possible optimizations used by alloc. If you're just trying to hide your ivars, there are better ways.
EDIT: I think you're looking for the class_addIvar function, which (as the name suggests) dynamically adds an ivar to a class. It only works with the new runtime, so it won't work on the simulator, but it will work on the iPhone.
EDIT 2: Just to be totally clear (in case it wasn't already), you can definitely rely on allocWithZone always being called. Fundamental Cocoa classes, such as NSString and NSArray, override allocWithZone. class_createInstance is almost never used except at the runtime level, so you don't have to worry about any parts of Cocoa using it on your classes. So the answer to the original question is "no" (or more specifically, objects are sometimes created without alloc, but not without allocWithZone, at least as far as I know).
Well there is nothing technically to stop you from overriding alloc. Just create a method in your class called +alloc. I just can't imagine any reason why you would need to.
Sounds like you are trying too hard to manage memory. Let the OS dynamically allocate memory when you create an object. If you are using too much, the OS will send a notification that you are getting close to the limit. At that point you can dealloc stuff you don't need anymore.
If you need so much memory that you have to use tricks, your implementation may need rethinking at the core level instead of trying to fit your square design into the round hole of the iPhone OS.
Just my opinion based on the info you provided.