Obj-C, properties for everything - objective-c

I have started work at a new company and one of the guidelines I have been told to adhere to by my team lead is to rarely use retain/release and instead rely on properties for memory management. I can see the appeal of keeping the code clear and leaving less room for mistakes but opening up the interfaces like this makes me uncomfortable. Generally speaking the architecture is very good but I have always been pedantic about closing up my classes to the outside world.
Is using properties like this an accepted design methodology in objective-c? Can anyone provide me with links or a clue where my new team may have picked up this strategy?

There is no need to expose properties to the entire world. In your implementation .m file you can add a little category to declare 'private' properties. E.g.
#import "Class.h"
#interface Class ()
#property (nonatomic, strong) NSDate *privateProperty
#end
#implementation Class
#synthesize privateProperty;
...
#end
Nothing in Objective-C is ever really private in strict terms, so I'd say this was good practice — it hides almost all of the retain/release stuff without requiring an ARC-compatible runtime and has the side effect of not requiring you to mention your instance variables in the header at all (though there are other ways to achieve that).
As a historical note, I think this was the first way to move instance variables out of the header — which is something permitted only by the 'new' runtime on iOS and 64bit Intel 10.6+ — so that may be a secondary reason why your team have settled upon it. Unless they've explicitly told you to make your classes transparent, they may actually be completely in agreement with your feeling (and the well accepted object oriented principle) that implementations should be opaque.

You don't have to declare your properties publicly. Using a class category or class extension, you can place your properties within the implementation.
For example:
// in AnObject.h
#interface AnObject : NSObject
#end
// in AnObject.m
#interface AnObject () // () is class extension, (foo) is a class category
#property (retain) NSString *foo;
#end
#implementation AnObject
#synthesize foo;
#end
For more information, see Apple's documentation.

Related

Diff between declaring in file scope and implementation

I am new to Objective-C and I was going through the code when I came across this:
#implementation ThreadManager
#synthesize bridge = _bridge;
NSMutableDictionary *threads;
Can I write this as:
#implementation ThreadManager {
NSMutableDictionary *_threads;
RCTBridge *_bridge;
}
Also can someone look at the code and please let me know if #synthesize bridge = _bridge; is actually being used? I think it's redundant.
In both cases, these are different things.
#synthesize creates accessors (-bridge and -setBridge:). Declaring an ivar in #implementation does not.
This style of #synthesize is not common today, and generally is unnecessary (as written, it's almost certainly the default for this property) (*). But it isn't replaced by an #implementation ivar. It's replaced by nothing. You just have to declare the #property. That said, it isn't hurting anything. See Declared Properties for details.
(*) I looked up the code you referenced, and I see why they're using #sythesize. bridge is declared in a protocol, not directly in the interface, so it is needed in this case.
threads here is a class variable, shared by all instances of ThreadManager (it's more typical to make these static, but it's not mandatory; in this form it's really just a global, but in practice that's the same thing). This isn't really an "Objective-C thing." It works just like regular C. Your modified code makes it an instance variable, which is different.
Declaring ivars in #implementation is pretty rare in modern ObjC. The only reason I've done it in years is to hold C++ properties in objects that expose pure-ObjC interfaces, or very occasionally to hold a private C-type that I want to manipulate directly (without accessors). The #property syntax is much nicer and more common.

Type-casting #property for concrete child class [duplicate]

This question already has answers here:
Overriding #property declarations in Objective-C
(2 answers)
Closed 9 years ago.
I am designing a abstract base class for a model, where one property of the base class is currently id. I'd like the concrete classes to define what this "content" property type is. Is it safe to redefine the property with a specific type for compiler checking?
Base class .h:
#interface Foo : NSObject
...
#property (nonatomic, strong) id content;
#end
Concrete class .h:
#interface TextFoo : Foo
...
#property (nonatomic, strong) NSString *content;
#end
Concrete class .m now requires a #synthesize for NSString *content. Is this override safe to do, or are there unintended side effects? At some top level controller I will be using introspection for a collection of Foos, so I'm really only looking for compiler checking on concrete classes.
Edit: Just to add some additional information, this does actually work (Xcode 5.0.2) with no warnings or errors from the compiler. The abstract base class can even assign an arbitrary object in a setter and the subclass setter/getter still works.
To be very honest some (or I should say many) programmers would consider this a poor architecture design. You can do this but should not be doing this.
As far as the "safety" is considered, that is solely your responsibility now with this approach as compiler won't back you up here (thanks to dynamic nature of Objective-C). Your code may become completely safe if you keep in mind that content is no more an id type.
There might arise a situation where you assign content of base class to let's say NSDictionary object (which is pretty much valid) and somehow (if you are drunk and coding) you end up assigning this value to child's content (again thanks to dynamic nature of Objective-C, its pretty much valid). So now in this case you are not safe and your app might crash somewhere. So the moral of the story is I am not saying No to Drunken Coding, but I am saying no to poor architecture.

Objective-C coding guidelines

So in the guidelines it says:
For code that will run on iOS only, use of automatically synthesized instance variables is preferred.
When synthesizing the instance variable, use #synthesize var = var_; as this prevents accidentally calling var = blah; when self.var = blah; is intended.
// Header file
#interface Foo : NSObject
// A guy walks into a bar.
#property(nonatomic, copy) NSString *bar;
#end
// Implementation file
#interface Foo ()
#property(nonatomic, retain) NSArray *baz;
#end
#implementation Foo
#synthesize bar = bar_;
#synthesize baz = baz_;
#end
Question is, does this apply to public variables only or private too? It's not really clear on the documentation, but would like to have some thoughts or perspective on why "if" this is only for public or private only? I think that it just makes sense for all public/private so that you don't mess up ivars and using the property
I don't think it particularly matters whether the variables in question are public or private. The practice of synthesizing under a different name makes it explicit when you are accessing the variable directly instead of using the generated accessor method.
Perhaps there's a different question underlying what you're asking: should I typically access private ivars via the accessor or directly? I think most skilled iOS devs tend to use accessors unless there is some particular reason not to (performance, avoiding side effects like KVO, etc.). Doing so is more future-proof and allows for flexibility in the underlying implementation. In a very small way, you're coding to an interface rather than an implementation.
It also might be worth pointing out that the default behavior of Clang is going to change in the future so that property-backing ivars are synthesized named _foo by default. Clearly the powers-that-be consider consider underscoring ivars to be a best-practice.
I am pretty sure much of it comes down to personal preferences, so here are mine, for what they are worth:
I like to distinguish between public properties and "private" instance vars.
Properties are always accessed through their accessors, except for initialization (and within a manually created accessor method, for obvious reasons). Hence, the underscore in the backing ivar is useful, and not really an issue in my daily use of the properties.
Instance vars are used to hold state that is used internally in the methods, but not (directly) by other classes.
I have become very fond of declaring my instance variables in the .m file. Nice, clean and easy (no switching back and forth between .h and .m to declare ivars).
I find that this distinction helps me clear my mind and determine if a property is something outside agents should get and/or set directly (a property in .h), or if it is really just a help to get my method implementations to work (an ivar in .m).
I'd agree with Paul.s. that consistency is your friend, but to me, distinction is a friend, too.

How should private and public members be implemented in objective-c?

I had some discussion related to the use of properties and instance variables at work, therefore I would like to find a wiki answer for that. Now, I know there's no real private member type in objective-c, everything is pretty much public. However, I'm a little bit concerned about the way we should design our classes and also to comply to OOP principles. I would like to hear opinions of these three design approaches:
A. According to various post and even to a new Stanford university iPhone development courses, you should always use properties everywhere you can. However IMHO, this approach brakes OOP design principles because in this case, all members become public. Why do I need to publish all my internal/local instance variables to outside? Also, there's some very little (but still) overhead if you use synthesized setters via properties, instead using local ivar directly. Here's a sample:
//==== header file =====//
#interface MyClass : NSObject
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#property (nonatomic, retain) NSString *propertyForPrivateMember;
#end
B. Another approach is to declare ivars in header file (without declaring relative properties) for private members, and in the same header file, to declare pure properties (without declaring relative ivars) for public members. In such case, ivars would be used directly in the class. This approach makes sense but not uses all benefits from properties because we have manually to release old values before setting the new ones. Here's a sample:
//==== header file =====//
#interface MyClass : NSObject{
NSString *_privateMember;
}
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#end
C. To declare pure properties (without declaring relative ivars) for public members in header file, and to declare pure properties (without declaring relative ivars) for private members in private interface in implementation file. This approach IMHO is more clear than the first one, but the same question remains: why do we have to have properties for internal/local members? Here's a sample:
//==== header file =====//
#interface MyClass : NSObject
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#end
//==== implementation file =====//
#interface MyClass()
#property (nonatomic, retain) NSString *propertyForPrivateMember;
#end
This decision freedom annoys me a little bit and I would like to find a confirmation from respective sources about how things should be done. However, I was unable to find such strict statements in Apple docs on that, so please post a link to apple docs if any exists, or to any other theory that clears that.
By using class extensions you can have private properties.
A class extension syntax is simple:
Inside the .m-file, that has the class, create a unnamed category:
.h
#interface OverlayViewController : UIViewController <VSClickWheelViewDelegate>
- (IBAction)moreButtonClicked:(id)sender;
- (IBAction)cancelButtonClicked:(id)sender;
#end
.m
#import "OverlayViewController.h"
#interface OverlayViewController ()
#property(nonatomic) NSInteger amount;
#property(retain,nonatomic)NSArray *colors;
#end
#implementation OverlayViewController
#synthesize amount = amount_;
#synthesize colors = colors_;
//…
#end
Now you got all the aspects of properties for private members, without exposing them to public. There should be no overhead to synthesized properties to written getter/setters, as the compiler will create more or less the same at compile time.
Note that this code uses synthesized ivars. No ivar declaration in the header is needed.
There is a nice cocoawithlove article, about this approach.
You also ask why to use properties for private ivars. There are several good reasons:
properties take care for ownership and memory management.
at any point in future you can decide, to write a custom getter/setter. i.e. to reload a tableview, once a NSArray ivar was newly set. If you used properties consequently, no other changes are needed.
Key Value Coding support properties.
public readonly properties can be re-declared to private readwrite properties.
Since LLVM 3 it is also possible, to declare ivars in class extensions
#interface OverlayViewController (){
NSInteger amount;
NSArray *colors;
}
#end
or even at the implementation block
#implementation OverlayViewController{
NSInteger amount;
NSArray *colors;
}
//…
#end
see "WWDC2011: Session 322 - Objective-C Advancements in Depth" (~03:00)
There really is not a clean, safe, zero overhead, solution to this which is directly supported by the language. Many people are content with the current visibility features, while many feel they are lacking.
The runtime could (but does not) make this distinction with ivars and methods. First class support would be best, IMO. Until then, we have some abstraction idioms:
Option A
Is bad - everything's visible. I don't agree that it is a good approach, and that is not OOD (IMO). If everything is visible, then your class should either:
support all cases for how the client may use your class (usually unreasonable or undesirable)
or you provide them with a ton of rules via documentation (doc updates are likely to go unnoticed)
or the accessors should have no side effects (not OOD, and frequently translates to 'do not override accessors')
Option B
Has the deficiencies of Option A,, and like Option A, members may be accessed by key.
Option C
This is slightly safer. Like all the others, you can still use keyed access, and subclasses may override your accessors (even if unknowingly).
Option D
One approach to this is to write your class as a wrapper over over an implementation type. You can use an ObjC type or a C++ type for this. You may favor C++ where speed is important (it was mentioned in the OP).
A simple approach to this would take one of the forms:
// inner ObjC type
#class MONObjectImp;
#interface MONObject : NSObject
{
#private
MONObjectImp * imp;
}
#end
// Inner C++ type - Variant A
class MONObjectImp { ... };
#interface MONObject : NSObject
{
#private
MONObjectImp imp;
}
#end
// Inner C++ type - Variant B
class MONObjectImp;
#interface MONObject : NSObject
{
#private
MON::t_auto_pointer<MONObjectImp> imp;
}
#end
(Note: Since this was originally written, the ability to declare ivars in the #implementation block has been introduced. You should declare your C++ types there if it isn't necessary to support older toolchains or the 'fragile' 32-bit OS X ABI).
C++ Variant A is not as 'safe' as the others, because it requires the class' declaration visible to the client. In the other cases, you can declare and define the Imp class in the implementation file -- hiding it from clients.
Then you can expose the interface you choose. Of course, clients can still access your members if they really want to via the runtime. This would be easiest for them to do safely with the ObjC Imp type -- the objc runtime does not support C++ semantics for members, so clients would be asking for UB (IOW it's all POD to the runtime).
The runtime cost for the ObjC implementation is to write a new type, to create a new Imp instance for each instance, and a good amount of doubling of messaging.
The C++ type will cost practically nothing, apart from the allocation (Variant B).
Option E
Other approaches often dissociate ivars from interfaces. While this is a good thing, it's also very unusual for ObjC types. ObjC types/designs often maintain close relations to their ivars and accessors -- so you'll face resistance from some other devs.
Similarly to C++, Objective C provides public, private, and protected scopes. It also provides a package scope which is similar to package scope as defined in Java.
Public variables of classes can be references anywhere in the program.
Private variables can only be referenced within messages of the class that declares it. It could be used within messages that belong to ANY instance of the same class.
Package scope is similar to public scope within the same image, i.e. executable or library. According to Apple’s documentation, on 64-bit architectures, variables of package scope defined within a different image are to be treated as private.
Variable scope is defined by #public, #private, #protected, #package modifiers. These modifiers can be used both in a way similar to C++ or Java. All variables listed under a scope declaration belong to the same scope. Also, variables can be listed on the same line where the scope is declared.
#interface VariableScope : NSObject {
#public
int iVar0;
#protected
int iVar1;
#private
int iVar2;
#package
int iVar3;
#public int iVar01, iVar02;
#protected int iVar11, iVar12;
#private int iVar21, iVar22;
#package int iVar31, iVar32;
}
#end
For more info use the below link
http://cocoacast.com/?q=node/100

Properties and Instance Variables in Objective-C

I'm rather confused about properties and instance variables in Objective-C.
I'm about half-way through Aaron Hillegass's "Cocoa Programming for Mac OS X" and everything is logical. You would declare a class something like this:
#class Something;
#interface MyClass : NSObject {
NSString *name;
NSArray *items;
Something *something;
IBOutlet NSTextField *myTextField;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSArray *items;
Since other objects need to manipulate our name and items instance variables, we use #property/#synthesize to generate accessors/mutators for them. Within our class, we don't use the accessors/mutators—we just interact with the instance variable directly.
something is just an instance variable that we're going to use in our class, and since no one else needs to use it, we don't create a pair of accessors and mutators for it.
We need to interact with a text field in our UI, so we declare an IBOutlet for it, connect it, and we're done.
All very logical.
However, in the iPhone world, things seem to be different. People declare properties for every single instance variable, declare properties for IBOutlets, and use accessors/mutators to interact with instance variables within the class (e.g. they would write [self setName:#"Test"] rather than name = #"Test").
Why? What is going on? Are these differences iPhone-specific? What are the advantages of declaring properties for all instance variables, declaring properties for IBOutlets, and using accessors/mutators within your own class?
In the iPhone world, there's no garbage collector available. You'll have to carefully manage memory with reference counting. With that in mind, consider the difference between:
name = #"Test";
and
self.name = #"Test";
// which is equivalent to:
[self setName: #"Test"];
If you directly set the instance variable, without prior consideration, you'll lose the reference to the previous value and you can't adjust its retain count (you should have released it manually). If you access it through a property, it'll be handled automatically for you, along with incrementing the retain count of the newly assigned object.
The fundamental concept is not iPhone specific but it becomes crucial in an environment without the garbage collector.
Properties are used to generate accessors for instance variables, there's no magic happening.
You can implement the same accessors by hand.
You can find in Aaron Hillegass's book examples of 3 memory management strategies for member variables. They are assign/copy/retain. You select one of those as required for given variable.
I assume you understand memory management in Objective-c ...
Accessors hide the complexity and differences of memory management for each variable.
For example:
name = #"Test"
is a simple assignment, name now holds reference to NSString #"Test". However you could decide to use copy or retain. No matter which version of memory management you chose accessor hides the complexity and you always access the variable with (or similar):
[self setName:#"Test"]
[self name]
Now setName: might use assign/copy or retain and you don't have to worry about it.
My guess is that iPhone tutorials use properties to make it easier for new developers to jump through memory management (even though it's handy to generate appropriate accessors with properties rather than implement them by hand every time).
However, in the iPhone world, things seem to be different. People declare properties for every single instance variable, declare properties for IBOutlets, and use accessors/mutators to interact with instance variables within the class (e.g. they would write [self setName:#"Test"] rather than name = #"Test").
That's not iPhone-specific. Except in init methods and the dealloc method, it's good practice to always use your accessors. The main benefit, especially on the Mac (with Cocoa Bindings), is that using your accessors means free KVO notifications.
The reason why people “declare properties for every single instance variable” is most probably that all of their instance variables are things they want to expose as properties. If they had something they would want to keep private, they would not declare a property for it in the header file. (However, they may make a property for it in a class extension in the implementation file, in order to get the aforementioned free KVO notifications.)
Declaring properties for outlets is overkill, in my opinion. I don't see a point to it. If you don't make a property, the nib loader will set the outlet by direct instance-variable access, which is just fine for that task.
I would suggest that modern development has made a very strong attempt to identify, define and apply best practices.
Among these best practices we find continuity and consistency.
Apart from arguing over use of accessors in init and dealloc methods, accessors should generally be used all the time (inside and outside of a class) for the benefits they offer, including encapsulation, polymorphic var implementations (which both allow for abstracting and refactoring) and to facilitate those best practices of continuity and consistency. The fundamental benefits of an object-orient language come into play when doing things in this way and exploiting the fullness of the language's capabilities. Always being consistent in one's coding is an oft undermentioned benefit, as any senior programmer will usually attest.
You can write like this
//MyClass.h
#class Something;
#interface MyClass : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSArray *items;
#end
//MyClass.m
#interface MyClass()
#property (nonatomic, strong) IBOutlet NSTextField *myTextField;
#property (nonatomic, strong) Something *something;
#end