Top properties Questions

List of Tags

What do atomic and nonatomic mean in property declarations?

@property(nonatomic, retain) UITextField *userName;

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName;

What is the functional difference between these 3?

Answered By: bbum ( 637)

The last two are identical; "atomic" is the default behavior (note that it is not actually a keyword; it is specified only by the absence of nonatomic -- atomic was added as a keyword in recent versions of llvm/clang).

Assuming that you are @synthesizing the method implementations, atomic vs. non-atomic changes the generated code. If you are writing your own setter/getters, atomic/nonatomic/retain/assign/copy are merely advisory. (Note: @synthesize is now the default behavior in recent versions of LLVM. There is also no need to declare instance variables; they will be synthesized automatically, too, and will have an _ prepended to their name to prevent accidental direct access).

With "atomic", the synthesized setter/getter will ensure that a whole value is always returned from the getter or set by the setter, regardless of setter activity on any other thread. That is, if thread A is in the middle of the getter while thread B calls the setter, an actual viable value -- an autoreleased object, most likely -- will be returned to the caller in A.

In nonatomic, no such guarantees are made. Thus, nonatomic is considerably faster than "atomic".

What "atomic" does not do is make any guarantees about thread safety. If thread A is calling the getter simultaneously with thread B and C calling the setter with different values, thread A may get any one of the three values returned -- the one prior to any setters being called or either of the values passed into the setters in B and C. Likewise, the object may end up with the value from B or C, no way to tell.

Ensuring data integrity -- one of the primary challenges of multi-threaded programming -- is achieved by other means.

What's the fastest way to count the number of keys/properties of an object? It it possible to do this without iterating over the object? i.e. without doing

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

(Firefox did provide a magic __count__ property, but this was removed somewhere around version 4.)

Answered By: Avi Flax ( 298)

To do this in any ES5-compatible environment, such as Node, Chrome, IE 9+, FF 4+, or Safari 5+:

Object.keys(obj).length

(Browser support from here)
(Doc on Object.keys here, includes method you can add to non-ECMA5 browsers)

141
davenpcj

I actually want to list all the defined variables and their values, but I've learned that defining a variable actually creates a property of the window object.

Answered By: Jason Bunting ( 186)

Simple enough:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

Now, you will not get private variables this way because they are not available.


EDIT: @bitwiseplatypus is correct that unless you use the hasOwnProperty() method, you will get properties that are inherited - however, I don't know why anyone familiar with object-oriented programming would expect anything less! Typically, someone that brings this up has been subjected to Douglas Crockford's warnings about this, which still confuse me a bit. Again, inheritance is a normal part of OO languages and is therefore part of JavaScript, notwithstanding it being prototypical.

Now, that said, hasOwnProperty() is useful for filtering, but we don't need to sound a warning as if there is something dangerous in getting inherited properties.

EDIT 2: @bitwiseplatypus brings up the situation that would occur should someone add properties/methods to your objects at a point in time later than when you originally wrote your objects (via its prototype) - while it is true that this might cause unexpected behavior, I personally don't see that as my problem entirely. Just a matter of opinion. Besides, what if I design things in such a way that I use prototypes during the construction of my objects and yet have code that iterates over the properties of the object and I want all inherited properties? I wouldn't use hasOwnProperty(). Then, let's say, someone adds new properties later. Is that my fault if things behave badly at that point? I don't think so. I think this is why jQuery, as an example, has specified ways of extending how it works (via jQuery.extend and jQuery.fn.extend).