Articles Tagged 'setters'

Objective-C: expose properties in a class

I would like to show and discuss some examples on how to add and manipulate properties in Objective-C class. : A classic example, precisely, is the following, in the definition of our interface class defines two properties nome and cognome :

1
2
3
4
5
6
7
8
9
10
11
/ / MyClass.h
# Import <Foundation/Foundation.h>

NSObject { @ Interface MyClass: NSObject {
nome; NSString * name;
cognome; NSString * name;
}

retain ) NSString * nome; @ Property (retain) NSString * name;
retain ) NSString * cognome; @ Property (retain) NSString * name;
@ End

e setter usati rispettivamente per leggere ed impostare le nostre due proprietà: In the implementation file the statement insert @synthesize so that Xcode will produce for us the methods getter and setter , respectively, used to read and set our two properties:

1
2
3
4
5
6
7
8
/ / MyClass.m
# Import "MyClass.h"

@ Implementation MyClass

@ Synthesize name, surname;

@ End

, possiamo scrive: When you're going to use our class MyClass , that is when istanziaremo an object of type MyClass , we can write:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/ / Any other class, as AppDelegate
/ / In the file. H
# Import <UIKit/UIKit.h>
# Import "MyClass.h"

@ Class TestViewController;

NSObject <UIApplicationDelegate> { @ Interface TesAppDelegate: NSObject {<UIApplicationDelegate>
UIWindow * window;
* TestViewController viewController;

MyClass * myClass;
}

/ / In the file. M
MyClass alloc ] ; myClass = [MyClass alloc];
"Giovambattista" ; miaClasse.nome @ = "Giovambattista";
"miaClasse.nome = %@" , miaClasse.nome ) ; NSLog (@ "miaClasse.nome =% @", miaClasse.nome);

Or, which is equivalent to:

1
2
3
/ / Always in the file. M
@ "Undolog" ] ; [SetNome myClass: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [myClass name]);

So far so good. However, it could mislead the equivalence of the "variable" internal (ivar) with the name of the property itself. To understand the difference, propose again the same as doing without, this time, the @synthesize . . Now, therefore, we should take care to write the methods getter and setter . To further emphasize the differences, will rename the internal variables by inserting an underscore before the name. But we see the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Import <Foundation/Foundation.h>

NSObject { @ Interface MyClass: NSObject {
_nome; NSString * _Name;
_cognome; NSString * _cognome;
}

NSString * ) nome; // get - ( NSString *) name; / / get
NSString * ) cognome; // get - ( NSString *) name; / / get

void ) setNome : ( NSString * ) stringaIngresso; // set - (Void) setNome: ( NSString *) stringaIngresso; / / set
void ) setCognome : ( NSString * ) stringaIngresso; // set - (Void) setCognome: ( NSString *) stringaIngresso; / / set

@ End

. Unlike the previous pointers to internal variables (incapsultate) have become _nome and _cognome . . @property è scomparso, in quanto non serve più. In addition there are four definitions of methods that represent our get and set . @property has disappeared, as no longer needed.
We see the implementation file MyClass.m :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Import "MyClass.h"

@ Implementation MyClass

/ / Get a "name"
NSString * ) nome { - ( NSString *) name {
_Name return;
}
/ / Set to "name"
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
_Name = stringaIngresso;
}

/ / Get for "surname"
NSString * ) cognome { - ( NSString *) name {
_cognome return;
}
/ / Set for "surname"
void ) setCognome : ( NSString * ) stringaIngresso { - (Void) setCognome: ( NSString *) {stringaIngresso
_cognome = stringaIngresso;
}

@ End

Written as a class can be used exactly like the previous one, namely:

1
2
3
4
5
6
7
8
MyClass alloc ] ; myClass = [MyClass alloc];
"Giovambattista" ; miaClasse.nome @ = "Giovambattista";
"miaClasse.nome = %@" , miaClasse.nome ) ; NSLog (@ "miaClasse.nome =% @", miaClasse.nome);

/ / Or, which is equivalent to:

@ "Undolog" ] ; [SetNome myClass: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [myClass name]);

e set , evidenziando – anche con l'aggiunta dell'underscore – le differenze tra il nome della proprietà e la sua ivar interna _nome . At the level of educational neglect @synthesize forced us to write "their own" methods get and set , highlighting - even with the addition dell'underscore - the differences between the property name and its internal ivar _nome .
permette un reale controllo del dato prima della sua impostazione (o prima della sua lettura) e quindi un reale incapsulamento per proteggere la variabile interna. At the functional level the personal use of the methods get and set allows real control of the data before its setting (or prior to its reading) and then a real encapsulation to protect the internal variable.
For example it would be possible to prevent the passage of empty strings to the property nome :

1
2
3
4
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
stringaIngresso == @ "" ) stringaIngresso = @ "senza nome" ; if (@ stringaIngresso == "") @ stringaIngresso = "no name";
_Name = stringaIngresso;
}

Further variation

If you want to use the internal variables with the underscore in front (who rpoviene Adobe Actionscript could be used as well) is not necessary to abandon the use of the directive @synthesize . Xcode makes it possible to "merge" the methods mentioned above:

1
2
_nome; @ Synthesize name = _Name;
_cognome; @ Synthesize name = _cognome;

. In doing so we could use the pointer to the internally _nome , "summed up" - to the outside - as a property nome . e setter , è vero anche che lo fa solo se non li trova, quindi se desiderate “implementare” un vostro metodo di getter e/o setter potete farlo anche se avete usato la direttiva @synthesize . Moreover, it is true that the use of @synthesize produces automatic generation methods (messages) of getter and setter , it is also true that if he does not find them, so if you want to "implement" a method for your getter and / or setter you can do this even if you used the directive @synthesize .

Memory allocations

In the examples above I have omitted some important details for a real implementation. First of all, I have not shown any method init() , useful for object initialization and default values. Moreover, there is the addition of a method dealloc() :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/ / File MyClass.m
# Import "MyClass.h"

@ Implementation MyClass

id ) init { - (Id) init {
self = [ super init ] ) { if (self = [super init]) {
"Nome preimpostato" ; _Name @ = "Preset Name";
"Cognome preimpostato" ; _cognome @ = "Preset Name";
}
return self;
}

void ) dealloc { - (Void) dealloc {
; [_Name Release];
; [_cognome Release];
; [Super dealloc];
}

NSString * ) nome { - ( NSString *) name {
_Name return;
}
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
stringaIngresso == @ "" ) stringaIngresso = @ "senza nome" ; if (@ stringaIngresso == "") @ stringaIngresso = "no name";
_Name = stringaIngresso;
}

NSString * ) cognome { - ( NSString *) name {
_cognome return;
}
void ) setCognome : ( NSString * ) stringaIngresso { - (Void) setCognome: ( NSString *) {stringaIngresso
_cognome = stringaIngresso;
}

@ End

, etc… In the future we will then see the details on the properties readonly , retain , etc ... :)

Continued ...

Add properties to a MovieClip

In Post Extend MovieClip in Flash MX I had some insight to extend a MovieClip. In particular, I said that the use of MovieClip.prototype not allow the extension of their methods, but only:

[...] Two important limitations of this technique are:

  1. It can not be applied to all objects exposed by Flash
  2. They can be "added" only methods and properties do not [...]

Indeed, it is possible, with an extra step, even when using dynamically add properties MovieClip.prototype . , infatti, Flash permetteva l'aggiunta di proprietà (in lettura/scrittura o solo lettura) tramite il metodo addProperty() . Before the introduction of function get and function set , in fact, allowed the addition of Flash properties (read / write or read only) via the addProperty() . In practice this results in the invocation of the method addProperty() and the definition of two getters and setters. The setter can be null in order to create read-only property. For example if we wanted to extend MovieClip with an all new property _alpha can add animation, just write the following code:

1
2
3
4
5
6
7
: Number { _get_alpha function (): Number {
this . _alpha ) ; return (this. _alpha);
}
v : Number ) : Void { _set_alpha function (v: Number ): Void {
this , "_alpha" , Strong . easeOut , this . _alpha , v , 1 , true ) ; new Tween instance (this, "_alpha", Strong. easeOut, this. _alpha, v, 1, true);
}
prototype . addProperty ( "_alpha_tween" , _get_alpha , _set_alpha ) ; MovieClip . prototype. addProperty ("_alpha_tween" _get_alpha, _set_alpha);

From now on, if we have a symbol "miosimbolo_mc" We can exploit this new property:

1
; miosimbolo_mc. _alpha_tween = 50;

. What you can do instead, is to overwrite the existing properties, which is why I used _alpha_tween instead of _alpha . Here, then, a good reason to still use the 2.0 classes to extend - and result - any MovieClip.

Continued ...


Stop SOPA