#properties question on iPhone development - iphone

From what I've read, #properties and #synthesize are used to tell the compiler to to generate getters and setters for various properties of our class.
So I am confused when I see the source code of an Apple example, the GKTank, that uses only one class for the whole game (apart from the app delegate) and still most of the attributes of that class are defined in #property() and are synthesized, even if no other class will try to get/set them. What am I misunderstanding here?
Thanks

Using properties is generally good practice as the synthesized setters will do the right thing when it comes to memory management (retain, or simply assign, depending on how you've configured your property).
They are also a means of providing a clean separation between the public interface of your class and it's internal implementation.
This article offers some good advice on when and why to use properties and dot-notation.

It also allows you to use the dot syntax:
self.myProperty = something;

I don't know that particular example. However, it is considered good style to access members of the same class through accessors rather than referencing the members directly. By encapsulating the members as a property with getters and setters, the implementation details of the field may change while those details are abstracted by the getter/setter.
Furthermore, the declaration of properties on the class allows you to use the .-notation to access the properties so it might lead to more consistent code if you want to use that notation.

Related

Swift: Constant's internal implementation

In swift, how is constants implemented?
I read this article, which says
In Swift, constants are generally implemented as (inlined) function calls.
I am not clear of this statement.
Does Swift use a special approach to make constants?
Could anyone explain?
Are you familiar with "getter" and "setter" methods from other languages, such as Java? If a variable is made public in a language like Java, it's exposed to other classes to access directly. In the future, if this variable has to be changed, there's no way to do so without changing all of the other classes dependent upon. With getter/setter methods, dummy implementations can be made that don't do anything besides read/write the value. In the case that a change needs to be made, the implementation of these methods can be changed without effecting the public API of the class.
Swift implements variables with "properties", which are like a backing private variable with public getter/setter methods that are automatically generated. In the future, you can replace a property with a computer property with a special getter/setter implementation, without effecting the public API of the class, just like before. The difference here is that you don't need to write all of the default getters/setters yourself.

Getters and setters for all the private variables of a class?

Is it really necessary or a good practice in general to add getters and setters on all the private variables of a class?
I am not asking about the read-only variables. What I am really asking is the general case, where most of the time we just add getters and setters in case they'll be needed and don't really know whether they will be used or not.
There are different explanations by different people regarding the use of 'getters' and 'setters'. The purest OO people says, they are evil.
But actually there are situations where we have to go with them at least in non-direct way.
But I believe that, it is not a good practice to add them seamlessly as you suggest.
As private properties are the internal state of the defining class there is no need to write accessors.
The benefits are:
faster code execution (less function calls),
higher readability and maintainability (lower LOC),
accessibility to private properties only for the defining class.
It is not necessary to write getter or setter for all private variables.
It is just a good practice.
But without any public function you can not access the private data(variable) of the class.

Private property declaration in your class implementation?

Sorry if it's too obvious for you. I'm still learning objetive-c and proper design patterns.
Could you explain me why it is a good idea to declare a property inside #interface in implementation file of a class as a private property? You just can use a local declaration of your type with a class scope, since nobody outside your class would use any getter or setter for this property.
Thanks.
By using the property semantics, you get memory management behavior handled 'for free' by the compiler. Even if your data is private within your class, having the compiler emit correct release/retain/copy saves time and mistakes down the line.
With the modern ARC compiler, this is probably less of an issue now.
When you declare something as #private, usually an instance variable or a property, it became only accessible in methods of the class that declared it. Trying to access it from a subclass results in an error.
I know you didn't asked for this but there is also #protected, when a property is declared like this, it becomes only accessible in methods of the class that declared it and in the methods of any class that inherits from that class.
The source for this info is the best book I know about Objective-C - Learning Objective-C 2.0 by Robert Clair.

Objective-C Private Method Dilemma

I'm aware that Objective-C doesn't support real private methods. What I'm currently doing to declare 'private' methods is adding the following to class .m files:
#interface MyClass()
- (void) privateMethodName;
#end
The Problem:
If I now add a subclass, and want to use this 'private' method, I can't! I get the error:
Receiver type 'SubClassName' for instance message does not declare a
method with selector 'privateMethodName'
So, if I don't want non-subclasses to be able to access this method, but do want subclasses to be able to, what can I do? What is the best/proper way of achieving my goal?
You could separate the "protected" interface from the public one. In the primary header, just declare the public methods:
MyMagicThingy.h:
#interface MyMagicThingy: NSObject
- (void) publicMethod;
#end
Then, have an additional header with protected methods:
MyMagicThingy+Protected.h:
#import "MyMagicThingy.h"
#interface MyMagicThingy (Protected)
- (void) protectedMethods;
#end
You cannot have "real" private/protected/public methods in Objective C (as in: the compiler will enforce access rules. All methods are public). You have to go with a convention.
What you describe is really a protected method. One approach to overcome this: Ivars can be declared #public, #protected, or #private. You could declare a protected helper instance to restrict access to derived instances, which then calls back through the object which holds it.
Another alternative in some cases would be to make the subclasses write to an interface, then keep your implementation private.
Sometimes, you just have to document "don't do this, unless you are not a subclass" because it's not part of the language. In this mindset, a separate header which declares a category of protected methods is one of my favorite. It's pretty well hidden from clients, but can be made visible to subclasses by explicit inclusion -- Dirk provided an example of this at the same time, check it out.
Lastly, if you're comfortable with ObjC++, C++ offers this control, so you can mix modes and visibility quite freely.
First and foremost
You can't get anyone to not being able to call any method that is implemented on an object in Objective-C (at least not without burning through several dozen razors making Yaks less weatherproof).
Just don't call methods that are not declared in public header files, as a convention (this is, what you're already doing).
Second
The word public in the above paragraph does the trick:
In Objective-C (at least in its current incarnation), a class's interface can be defined over any number of header files using the technique you just described in your post: Class continuations.
One such example of an Apple framework class doing that would be UIGestureRecognizer with its separate subclassing header UIGestureRecognizerSubclass.h.
PS:
The error you are seeing reeks of using ARC so your runtime is definitely recent enough to even use multiple implementation files for that.

Is it good style to declare methods in .h when they're intended to be overwritten by subclass?

I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.
But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).
Must I declare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?
Related: Is there a way to create an abstract class in Objective C?
Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:
Abstract Classes
Some classes are designed only or
primarily so that other classes can
inherit from them. These abstract
classes group methods and instance
variables that can be used by a number
of different subclasses into a common
definition. The abstract class is
typically incomplete by itself, but
contains useful code that reduces the
implementation burden of its
subclasses. (Because abstract classes
must have subclasses to be useful,
they’re sometimes also called abstract
superclasses.)
Unlike some other languages,
Objective-C does not have syntax to
mark classes as abstract, nor does it
prevent you from creating an instance
of an abstract class.
The NSObject class is the canonical
example of an abstract class in Cocoa.
You never use instances of the
NSObject class in an application—it
wouldn’t be good for anything; it
would be a generic object with the
ability to do nothing in particular.
The NSView class, on the other hand,
provides an example of an abstract
class instances of which you might
occasionally use directly.
Abstract classes often contain code
that helps define the structure of an
application. When you create
subclasses of these classes, instances
of your new classes fit effortlessly
into the application structure and
work automatically with other objects.
So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.
You can also use a protocol to force classes to implement certain methods.
However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.
Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.
You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.
#interface MyBaseClass : NSObject {
}
- (void)foo;
#end
#interface MyBaseClass(ProtectedMethods)
- (void)bar;
#end
#interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
#end
You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.
Your base class can log, assert, or throw when an abstract/pure-virtual method is called.
As other people have said, Objective-C does not support pure virtual classes.
You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:
- (void)iMustBeImplementedInaSubclass;
{
[self doesNotRecognizeSelector:_cmd]; // Pure virtual
}
As ben says you are probably better served by using a protocol to get your API design right.