Access Instance Variables Directly from Initializer Methods

Access Instance Variables Directly from Initializer Methods

Properties should always be used to access instance variables of an object externally, but how you access instance variables internally is a hotly debated topic within the Objective-C community. Some suggest always using a property to access instance variables, some suggest always accessing the instance variable directly, and some suggest a mixture of the two. I strongly encourage you to read instance variables using direct access but to set them using the property, with a few caveats.

Consider the following class:

@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;

// Convenience for firstName + ” ” + lastName:
– (NSString*)fullName;
– (void)setFullName:(NSString*)fullName;
@end

The convenience methods fullName and setFullName: might be implemented like this:

- (NSString*)fullName {
return [NSString stringWithFormat:@”%@ %@”,
self.firstName, self.lastName];
/** The following assumes all full names have exactly 2
*  parts. The method could be rewritten to support more
*  exotic names.
*/
– (void)setFullName:(NSString*)fullName {
NSArray *components =
[fullName componentsSeparatedByString:@” “];
self.firstName = [components objectAtIndex:0];
self.lastName = [components objectAtIndex:1];
}

In both the getter and the setter, we access the instance variables via the accessor methods, using the property dot syntax. Now suppose that you rewrote both methods to access the instance variables directly:

- (NSString*)fullName {
return [NSString stringWithFormat:@”%@ %@”,
_firstName, _lastName];
}

– (void)setFullName:(NSString*)fullName {
NSArray *components =
[fullName componentsSeparatedByString:@” “];
_firstName = [components objectAtIndex:0];
_lastName = [components objectAtIndex:1];
}

The two styles have a few differences.

 Direct access to the instance variables will undoubtedly be faster, as it does not have to go through Objective-C method dispatch. The compiler will emit code that directly accesses the memory where the object’s instance variables are stored.

 Direct access bypasses the property’s memory-management semantics defined by the setter. For example, if your property is declared as copy, directly setting the instance variable will not cause a copy to be made. The new value will be retained and the old value released.

 Key-Value Observing (KVO) notifications would not be fired when accessing the instance variables directly. This may or may not be a problem, depending on how you want your objects to behave.

 Accessing through properties can make it easier to debug issues surrounding a property, since you can add a breakpoint to the getter and/or setter to determine who is accessing the properties and when.

A good compromise is to write instance variables using the setter and to read using direct access. Doing so has the benefit of fast reading and not losing the control of writing via properties. The most important reason for writing via the setter is that you will ensure that the memory-management semantics are upheld. There are, however, a few caveats to that approach.

The first caveat is when values are set within an initializer method. Here, you should always use direct instance variable access, because subclasses could override the setter. Consider that EOCPerson has a subclass EOCSmithPerson that is designed to be used only for people whose last name is “Smith.” This subclass might override the setter for lastName like so:

- (void)setLastName:(NSString*)lastName {
if (![lastName isEqualToString:@”Smith”]) {
[NSException raise:NSInvalidArgumentException
format:@”Last name must be Smith”];
}
self.lastName = lastname;
}

The base class EOCPerson might set the last name to the empty string in its default initializer. If it did this through the setter, the subclass’s setter would be called and throw an exception. However, there are some cases in which you must use the setterin an initializer. This is when the instance variable is declared within a superclass; you cannot access the instance variable directly anyway, so you must use the setter.

Another caveat is when the property uses lazy initialization. In this case, you have to go via the getter; if you don’t, the instance variable will never get a chance to be initialized. For example, the EOCPerson class might have a property to give access to a complex object representing each person’s brain. If this property is infrequently accessed and expensive to set up, you might initialize it lazily in the getter, like this:

- (EOCBrain*)brain {
if (!_brain) {
_brain = [Brain new];
}
return _brain;
}

If you were to access the instance variable directly and the getter had not been called yet, brain would not have been set up, and you would need to call the accessor for all accesses to the brain property.

Things to Remember

 Prefer to read data directly through instance variables internally and to write data through properties internally.

 Within initializers and dealloc, always read and write data directly through instance variables.

 Sometimes, you will need to read data through properties when that data is being lazily initialized.

You should always access the instance variables directly from within an initialization method because at the time a property is set, the rest of the object may not yet be completely initialized. Even if you don’t provide custom accessor methods or know of any side effects from within your own class, a future subclass may very well override the behaviour.

Inyección de dependencias en iOS

¿Que sucede cuando vamos al médico y te inyectan una vacuna? Pues la respuesta es sencilla, entran en tu cuerpo nuevas maneras de reaccionar ante posibles situaciones, sin que esto implique tengas que volver a nacer de nuevo.

Esto consiste el patrón de diseño Inyección de Dependencias, colocar dentro de un objeto vivo otros que puedan cambiar su comportamiento, sin que esto implique volver a crear el objeto de nuevo.

De esta manera, en tiempo de ejecución, creamos un método capaz de definir el nuevo comportamiento, asignando una instancia de objeto diferente a la que tenía hasta el momento.

Tiene dos ventajas fundamentales cuando estamos creando un producto a largo plazo.

Creamos un catálogo de piezas de software que podemos cambiar y modificar en el tiempo por otras mejores. Cuando creamos una aplicación que crecerá gracias a otros programadores está genial cuando se trata de una aplicación grande y que debe resistir a los envites del tiempo y de los programadores que la tocan, pero quizá si es más pequeña y tu vas a ser el responsable de todo, no sea tan buena opción, porque como todo en la vida, no hay nada que sume sin que reste por otro lado.

Así que con inyección de dependencias, más que poseer objetos lo que tenemos son colaboradores que se establecerán en tiempo de ejecución usando un inicializador de conveniencia o con usando el setter de una propiedad.

- (id)initWithTrafficClient:(id<TrafficClient>)trafficClient
{
    self = [super init];
    if (self) 
    {
        _trafficClient = trafficClient;
    }
    return self;
}

Podemos sustituir a un actor para que cumpla un rol, y si quieres cambiar esa implementación en el futuro, sólo tendrás que cambiar esa declaración.

Al eliminar el fuerte acoplamiento, no necesitamos comprender todos los problemas a la vez, y nos será más sencillo evolucionar el diseño de la aplicación según conozcamos los nuevos requisitos.

Las clases serán más sencillas de probar, gracias a usar mocks simples en lugar de colaboradores concretos, incluso los colaboradores reales pero configurados para nuestro escenario de pruebas específico.

Promoveremos la separación de responsabilidades mediante un claro contrato entre las clases, donde es fácil ver que clase necesita a otra para poder hacer su trabajo.Podemos pintar la arquitectura de una aplicación usando roles sencillos, y asignar a cada desarrollador  la responsabilidad de hacer la implementación sin romper la aplicación y sin impactar en el resto del equipo.

 

Como punto negativo destacar que podemos perder simplicidad en la depuración en módulos en proyectos externos ya que es preciso recompilar estos para poder modificarlos. 

Tabla periódica de tipografías en Español

Tabla periódica de tipografías en Español

Tabla periódica de tipografías

// Listing all fonts on iOS 7 sdk

NSArray * familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]];
// Iterating over the array familyNames
[familyNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSLog(@”Family %i: %@ “,idx+1, obj);

NSArray * fontNames = [[NSArray alloc] initWithArray:[UIFont fontNamesForFamilyName:[familyNames objectAtIndex:idx]]];

// Iterating over the array fontNames
[fontNames enumerateObjectsUsingBlock:^(id obj, NSUInteger inxFont, BOOL *stop) {
NSLog(@” Font name : %@”, [fontNames objectAtIndex:inxFont]);
UIFont *sampleFont = [UIFont fontWithName:[fontNames objectAtIndex:inxFont] size:14.0]; }];

}];
Continue reading Tabla periódica de tipografías en Español

Rápida guía de referencia de resoluciones de pantalla en iOS

DISPOSITIVO iPhone iPhone Retina iPhone 5 iPad iPad Retina
DISPOSITIVO iPhone 1g-3GS
iPod Touch 1g-3g
iPhone 4
iPhone 4S
iPod Touch 4g
iPhone 5
iPod Touch 5g
iPad
iPad 2
iPad Mini
The New iPad
Resolución 480 x 320 960 x 640 1136 x 640 1024 x 768 2048 x 1536
Nombre fichero file.png or
file~iphone.png
file@2x.png or
file@2x~iphone.png
file-568h@2x~iphone.png file~ipad.png file@2x~ipad.png
 

Table View con dos secciones

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0)
    {
        return 1;
    }
    else {
        return self.googleAnswersArray.count;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell * cell;
    if (indexPath.section == 0) {
        
        cell = [self.tableView dequeueReusableCellWithIdentifier: @"userQuestionCell"];
        
        [self configureUserQuestionCell:(UserQuestionCell *)cell];
        
    }
    else if (indexPath.section == 1) {
        
        cell = [self.tableView dequeueReusableCellWithIdentifier: @"googleAnswerCell"];
        GoogleAnswer *googleAnswer = [self.googleAnswersArray objectAtIndex:indexPath.row];
        [self configureCell:(GoogleAnswerCell *)cell forGoogleAnswer:googleAnswer];
    }
    return cell;
}

- (void)configureCell:(GoogleAnswerCell *)cell forGoogleAnswer:(GoogleAnswer *)googleAnswer {
    
   // cell.textLabel.text = [[managedObject valueForKey:@"title"] description];
    
    cell.titleLabel.text = googleAnswer.title;
    cell.snippetLabel.text = googleAnswer.snippet;

    
    cell.linkToOpenURL =[NSURL URLWithString:googleAnswer.link];
    
}

- (void) configureUserQuestionCell:(UserQuestionCell *)cell
{
    if (editingModeFlag)
    {
        cell.userQuestionTextField.text = _userQuestion;
    }
    else {
        if ([_userQuestion length]>0)
        {
//            cell.userQuestionTextField.text = _userQuestion;
               cell.userQuestionTextField.text  = [NSString stringWithFormat:@"%@\n\nPulse Para Editar",_userQuestion];
            

        }
        else {
            cell.userQuestionTextField.text = @"Pregúntaselo a Susan";
        }
    }
    cell.userQuestionTextField.delegate = self;
}


Personalización de celdas con storyboard

Personalización de la celda.

En el Inspector de atributos de XCode, configuramos el comportamiento:

1.- Queremos personalizar nuestra celda, indicamos Style es Custom.

2.- En identifier, la clase que mapea el comportamiento de la celda.

3.- En accesory, Disclosure Indicator, que corresponde a la flecha >

Como no nos interesa que sea editable, indicamos que la acción es de no edición.

CellView Setting with Storyboard

Ahora tenemos que gestionar la llamada desde el Controlador hacia el nuevo view controller.

Como necesitamos pasarle los parámetros de la celda seleccionada por el usuario, debemos preparar el destino del segué con el parámetro que deseamos que trabaje. El parámetro en este caso es la respuesta de google que se deberá mostrar en el View Controller destino.

]
// Asking the tableView for the <strong>IndexPathForCell</strong>, which returns an index path representing the row and section of a given table-view cell.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([sender isKindOfClass:[GoogleAnswerCell class]])
    {
        // Setting de destination View Controller
        DetailedAnswerViewController * detailedAnswerViewController = segue.destinationViewController;

        NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
        detailedAnswerViewController.googleAnswerToShow = [self.googleAnswersArray objectAtIndex:indexPath.row];
    }
}

Un plan diferente, aprende a hacer jabones con tus manos

¿Mis planes para el finde? Pues es un plan divertido, mañana voy a pasa el día en familia a la sierra de Madrid haciendo cosas diferentes con una escuela rural  llamada Espíritu del Bosque.

Además de pasar un día fresquito y refrescante voy a aprender a realizar de forma natural jabón, gel y champú. Es algo que me llama mucho la atención y que voy a tener la oportunidad de aprender.

El jabón generalmente es el resultado de la reacción química entre un álcali (generalmente hidróxido de sodio o de potasio) y algún ácido graso; esta reacción se denomina saponificación, aunquel las ranas y sapos no tienen nada que ver.

El ácido graso puede ser de origen vegetal o animal, por ejemplo, manteca de cerdo o aceite de coco.

Imagen

Si te pica la curiosidad puedes verlo en su canal de videos en youtube

http://www.youtube.com/user/elespiritudelbosque1?feature=mhee 

FACEBOOK:https://www.facebook.com/elespiritudelbosque También os dejo el contacto por si alguien le apetece ir: www.espiritubosque.es 918908781 / 616552735