encapsulation in objective c - objective-c

I am a bit confused about encapsulation. In general (or in Obj-C), does it mean separation of interface/implementation OR does it imply access of ivars through methods ?
Please clarify. Thank you.

Actually, Both.
As nacho4d said, you encapsulate instance variables within your class and prevent direct access to them by using methods and properties to read and write their values. This ensures that the instance can always know when something has read or written a value whereas direct ivar access is no different from setting a value in a C struct.
However, the separation of #interface from #implementation also contributes greatly to encapsulation. And one of the goals of the enhancements to the language in the past few years has been to increase the degree of encapsulation offered by that separation.
Namely, the class's primary #interface can now contain only the parts of your class that you want other developers/code to interact with. The public interface, if you will. All of the implementation details can be moved out of the #interface in the latest compilers, including all instance variables.

The latter. From wikipedia:
A language mechanism for restricting
access to some of the object's
components.
Specifically in Objective-C an ivar will be #protected by default, so they only can be accessed within the same class or subclasses. can change it to #private or #public as you need.
The methods you mentioned are accessors (getters and setters) and in that case you probably want to use #properties since they can be defined in 1 line and you can set some attributes like retain, assign, copy, readonly, etc.
Read further on properties here (Apple doc)

Hiding of Class methods and variables from once class to other is called encapsulation.

Related

Does Apple recommend using class extensions or variable blocks in implementation?

Apple's doc mentions two ways to create private variables, namely property and ivar, but it does not say which is the preferred way. Which one is Apple's recommended approach or are they equally good in Apple's view?
#interface MyClass ()
#property (nonatomic, strong) NSObject *prop;
#end
or
#implementation MyClass {
NSObject *_prop;
}
Note - I am not asking for personal opinion, but Apple's recommendation. There are similar discussion on this but most have been viewed from personal opinion with no clarification on why one is better than the other and which way Apple advocates (though 99% of Apple sample code uses property)
You should always use #properties because they are safer (e.g. they contain the thread-safe access protection for atomic properties, etc).
And you should also always access properties via their getter/setter instead of directly accessing the instance variables (except in init methods).
As for Apple's recommendations:
Apple engineers answered that at some talks during past WWDC. Sorry no written reference, but I can confirm that they recommend properties over instance variables
In Apple's "Programming With Objective-C" Programming Guide, they mention that you should always prefer using properties over instance variables:
Although it’s best practice for an object to access its own properties using accessor methods or dot syntax, it’s possible to access the instance variable directly from any of the instance methods in a class implementation.
[...]
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self
[...]
The exception to this rule is when writing initialization, deallocation or custom accessor methods
Actually in such Programming Guides, like here where they describe the anatomy of an ObjC class, they never mention instance variables and explain how to create them, they only explain properties, so that's a pretty strong indicator that they try to enforce them anyway.

Modern Objective-C (2013) and declaring ivars/using #property, #dynamic, and #synthesize

With the current version of Objective-C, what are the official standards and best practices for declaring ivars, using #property and #synthesize? There are a lot of posts and resources on the topic but most of them are fairly antiquated from a year or two ago. I recently learned to only declare ivars in a statement block in the implementation of a class so that the encapsulation principles of OOP aren't broken but is declaring ivars even necessary in this day and age? What would be a possible use case where doing:
#interface MyClass()
#property (nonatomic) NSString* data;
#end
#implementation MyClass{
#private
NSString* _data;
}
#end
is necessary? To further that, is it ever necessary to use #synthesize? My understanding is that using #property will auto-synthesize both the accessor methods as well as the backing ivars. I've done some experimentation and I noticed that when I don't declare NSString* _data', I can still access_data' in my class implementation. Does that mean that declaring ivars come down to a matter of style, up to the discretion of the programmer? Could I condense my code and remove all ivar declarations in the statement blocks in my implementation and just use #property in my private interface? If that's not the case, what are the advantages and disadvantages of explicitly declaring ivars?
Finally, #dynamic. From what I can gather, it's used to say to the compiler, "Hey compiler, don't auto-generate the accessor method and don't worry if you don't find an implementation for it, I'll provide one at runtime". Is that all #dynamic is used for or is there more to it?
I just want to clarify all these things because it seems like there's a lot of different opinions and that there's not necessarily one right answer. Plus as Objective-C grows and progresses, those answers will change so it'll be nice to have a concise and up-to-date guide. Thanks everyone!
(Also if there's anything that I could word better or make clearer, let me know)
EDIT:
In summary, what I'm asking is this:
1) Is declaring ivars with modern Objective-C necessary?
2) Can I achieve the same effects of declaring ivars and corresponding properties by just using #property?
3) What is #dynamic used for?
4) Can I completely forgo the use of #synthesize or is there a good use case for it?
Upvote and down vote as you see fit.
There's a lot to answer here. I'll break it down:
Declaring ivars
As you've correctly noted, modern versions of the compiler will synthesize backing instance variables for declared #properties. The exception to this is on 32-bit Macs, where the modern Objective-C runtime, including non-fragile instance variables, is not available. Assuming your application is not targeting 32-bit OS X, you don't need to explicitly declare the backing ivar for an #property.
If you still want to use an ivar directly, without a corresponding #property (something I consider a bad idea most of the time), you of course must still explicitly declare the ivar.
#dynamic
#dynamic is as you've said meant to tell the compiler "don't synthesize accessors for this property, I'll do it myself at runtime". It's not used all that often. One place it is used is in NSManagedObject subclasses, where if you declare a modeled property in the header, you don't want to compiler to complain that there's no implementation of accessors for that property, nor do you want it to generate accessors itself. NSManagedObject generates accessors for modeled properties at runtime. The story is similar for custom CALayer subclasses.
#synthesize
#synthesize explicitly tells the compiler to synthesize accessor methods, and (on iOS and 64-bit Mac) a corresponding ivar for the specified property. There are three main cases where you still need to use it:
32-bit Mac apps.
If you've written your own custom setter and getter (or just getter for readonly properties). In this case, the compiler won't synthesize accessors because it sees yours. However, it also won't synthesize the backing ivar. So, you must use #synthesize someProperty = _someProperty;, to tell the compiler to synthesize an ivar. It still won't synthesize accessor methods of course. Alternatively, you can explicitly declare a backing ivar. I favor using #synthesize in this case.
If you want to use a different name for the property's backing ivar than the default (property name with an added underscore prefix). This is rare. The main case I can think of for using it is when transitioning existing, older code, that includes direct ivar access and where the ivars are not underscore-prefixed.
Best current practice seems to be to use properties for all ivars placing the property either in the .h file if they are to be exposed and in the .m file in a class extension if local to the class.
No #synthesize is needed unless the ivar needs to be different than the underscore prepended property name.
Yes, #dynamic is as you describe.
Further, it is no longer necessary to declare local instance methods or order such that the method is above the use.
First off, #synthesize is gone for these scenarios: do not have to do it any more.
Secondly, you don't need the private ivar anymore either.
So in essence, you can just do properties.
The way of controlling access is the same idiom that had become popular before MOC dropped: put the property in the public interface as readonly and then make a readwrite version in the private interface (which should be, as you show above, merely the name with open and close parens).
Note also, that many of the things that cluttered up the public interface in the past can now ONLY be in the private interface, so for instance IBOutlets, etc., since the controller is going to be the only thing diddling them.
I never see #dynamic used anywhere except in CoreDate-generated entities.
For someone who first worked with C++ where the dream was always that the header/interface merely show the user of the class what they needed and all other details would be hidden, I think MOC (Modern Objective C) is a dream come true.
BTW, highly recommend the intro session from WWDC Modern Objective C (from 2012) and the one this year was great too.

Is it possible to extend(heritance) class in Objective-c as is traditionally conceptualised in other languages?

I am having a lot of repeated code throughout my app classes given that some properties & method are stable across all my views.
I am looking to extend whatever class I am working with so that it automatically inherit all properties and methods that I think should be common to those classes.
I looked into the apple guide on extending classes. But I am left confused in the terms of the level of heritance that I can achieve.
I've successfully created Categories on lets say a UIViewController. But that limits me to only be able to declare Methods. I can not declare Properties on my Category and call them in side my Category or in the Extended Class. I want to be able to declare Properties and use it inside and outside my Extended-Class.
Its my first time trying to extend a class in objective-c taking full advantage of heritance but I do not know if it is possible. Am I missing something?
As an example in the code below every time I try to instantiate activityIndicatorView inside my method _activityIndicator it wouldn't recognise it. I've tried #syntetize and #dynamic but it doesn't work
NOTE: I am seeking an answer based on how to achieve heritance of methods and propeties. not highlighting what categories cant do (as I already tried and know I cant have properties there)
My attempt went as far of
#import <UIKit/UIKit.h>
#interface UIViewController (customViewController1)
#property (strong, nonatomic) UIView *activityIndicatorView;
- (void) _activityIndicator;
#end
#import "UIViewController+customViewController1.h"
#implementation UIViewController (customViewController1)
- (void) _activityIndicator {
//......
}
Your question is too broad, plus it is not clear what your problem is. Yes, you can subclass in Objective-C.
This is all very well documented in Apple's document "Object-Oriented Programming with Objective-C", section "The Object Model", subsection "Inheritance".
Categories are a nice way to add functionality while at the same time conforming to an object oriented principle to prefer composition over inheritance.
Categories only add methods, you can't add variables to a class using categories. If the class needs more properties, then it has to be subclassed.
When you use the term “extend”, you're talking about creating a subclass. This is, IIRC, how the term is used in Java and some other languages.
Apple uses the term differently (as Hermann Klecker hinted in his first comment). They literally mean extending an existing class with more functionality (in the form of methods)—that's what categories do. This is the normal English definition; extending something in the real world generally does not create a new thing.
Objective-C supports subclasses, too; it just doesn't call them “extending” the superclass. It's called creating a subclass, which inherits from the superclass.
Strctly spoken you cannot add a property to an existing class any differnt than creating a subclass.
If you cannot halp yourself and subclassing is not an option, then you can extend the class with getters and setters for the property that you want to store within the class.
Instead of really storing it as a member/instance variable/property, which you can't do, you could store the object (it cannto be a scalar, must be an object) in the global space using objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
This is some sort of global dictionary with two keys, the key itself and the ojbect to which you want to associat the stored object to. In your case that is the object of the type of the exended class. The setter stores it there and the getter receives it from there using objc_getAssociatedObject.
You delete an association by sending nil as value to objc_setAssociatedObject
AFAIK retained associated objects (values) are released shortly after the object that holds the associateion (object) is deallocated.
For further details see the Ojbective-C Runtime Reference https://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
Just: I do not say that this is strictly following the OO paradigm. :-)

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.

Data encapsulation...?

Would anyone be able to explain to me what data encapsulation in Objective-C is? I've been told that this an important concept of Objective-C but I don't see why...
Explain it to me as if I was 5 and then as if I was 25....
Thanks for your time,
~Daniel
From http://mobile.tutsplus.com/tutorials/iphone/learn-objective-c-2/ :
What we mean by data encapsulation is
that data is contained (so to speak)
by methods meaning to access it we
need to use methods. Some of you who
have programmed in other languages and
havenʼt heard of data encapsulation
may be wondering why we do things this
way. The answer is that by
encapsulating data, there is a nice
cushion between the developer of a
class and the user of a class. Because
the class methods manage and maintains
the attributes within the class, they
can more easily maintain data
integrity. Another major benefit is
that when a developer distributes his
class, the people using it donʼt have
to worry about the internals of the
class at all. A developer may update a
method to make it faster or more
efficient, but this update is
transparent to the user of the class
as he/she still uses the same method
with no change to his/her code.
In simple terms, the user is provided with what the developer wanted them to have, and "protects" everything else. The developer can change anything internal without the user having to rewrite their code.
If developers did not conform to data encapsulation, we would need to rewrite our code every time a new version of a library, code snippet, or an entire program was released.
Data encapsulation in Objective-C means that only the class itself should touch it's instance variables. Therefor you should always mark them as private, and only expose them through properties, as this:
#interface Foo : NSObject {
#private
int numberOfBars;
Baz* contentBaz;
}
#property(nonatamic, assign) int numberOfBars;
#property(nonatomic, retain) Baz* contentBaz;
#end
This means that the class can implement validation in it's setter methods. And even better if you use #synthesizeto generate your getter and setters than you need not even worry about the memory model of Cocoa at all (with the exception of releasing your ivars in dealloc).