52 effective methods - try to access instance variables directly inside the object

Keywords: iOS Attribute

Try to access instance variables directly inside the object

When reading data inside an object, it should be read directly through instance variables, while when writing data, it should be written through attributes.

  • _name = @"Jack" does not send messages through setter, and directly assigns values to variables, which is fast.
    For the following name attribute: @property (nonatomic, copy) NSString *name;
    The direct assignment is: _name = @"Jack"; through self.name = @"Jack", it is actually equivalent to _name = @"Jack".copy.
  • self.name = @"Jack" will trigger KVO, and "Jack" will not
    -self.name = @"Jack" can debug breakpoint in setter method, you know every assignment.
  • So a reasonable compromise is to use nsstring * STR = ﹣ name when reading data, and self.name = @"Jack" when assigning value.

When accessing instance variables within an object, whether to access them through the property (self.proper) or through ﹐ proper depends on whether to execute the setter and getter methods of the property.

  • If the setter and getter methods of the proper ty are executed, they are accessed through \

  • If the setter and getter methods of the property are not executed, they are accessed through the property (self.proper).
@interface Wrestler : NSObject
 
@property (copy, nonatomic) NSString *name; // Declare name as an attribute
 
- (void)smell;
 
@end
 
@implementation Wrestler
@synthesize name = _name; // The attribute name can be directly accessed by using the instance variable ﹣ name
 
- (void)setName:(NSString *)aName {
    NSLog(@"Set name");
    _name = [aName copy];
}
 
- (NSString *)name {
    NSLog(@"Get name");
    return [_name copy];
}
- (void)smell {
    NSLog(@"*** Smelling ***");
    
    // Using dot syntax to access instance variables
    NSLog(@"%@", self.name);
    
    // Directly calling the getter method of the property
    NSLog(@"%@", [self name]);

In initialization method and dealloc method, data should always be read and written directly through instance variables.

  • Subclasses may copy setter methods, and using self.proper = @ '' may not be equivalent to _proper = @ ''. Copy.

  • We write a subclass Cena of Wrestler, which inherits the property name and rewrites its setter method. This method will first check whether the name suffix is Cena, or throw an exception.
@interface Cena : Wrestler
 
- (instancetype)initWithName:(NSString *)aName;
 
- (void)wrestle;
 
@end
 
@implementation Cena
@synthesize name = _name;
 
- (instancetype)initWithName:(NSString *)aName {
    self = [super init];
    
    if (self) {
        NSLog(@"self.name = aName");
        self.name = aName;
    }
    
    return self;
}
 
- (void)wrestle {
    NSLog(@"I'm %@, U can't see me", self.name);
}
 
- (void)setName:(NSString *)aName {
    if (![aName hasSuffix:@"Cena"]) {
        [NSException raise:NSInvalidArgumentException format:@"last name must be Cena"];
    }
    
    _name = [aName copy];
}
 
@end
  • Initialize name as a blank string @ "" in the init method of parent class Wrestler
 (instancetype)init {
    self = [super init];
    
    if (self) {
        NSLog(@"self.name = empty string");
        self.name = @"";
    }
    
    return self;
  • call
        Cena *cena = [[Cena alloc] initWithName:@"John Cena"];
        [cena wrestle];
  • Run crash. Reason: self.name = @ "";. Call the setter method of the overridden name in the subclass. The blank string obviously does not have the @ "Cena" suffix, thus throwing an exception.

Data configured with Lazy Initialization should be read through properties.

@property (strong, nonatomic) NSNumber *chamCount;
- (NSNumber *)chamCount {
    if (!_chamCount) {
        _chamCount = @13;
    }
    
    return _chamCount;

Do not invoke the setter/getter method in the setter/getter method.

  • Modify the setter method above:
- (void)setName:(NSString *)aName {
    NSLog(@"Set name");
//    _name = [aName copy];
    self.name = aName;
}
  • Run the program, the console keeps outputting Set name, which crashes.
  • Reason: calling the setter method in the setter method will continue to nested calls, resulting in a program crash. The getter method is the same.

Main points

  1. When reading data inside an object, it should be read directly through instance variables, while when writing data, it should be written through attributes.

  2. In initialization method and dealloc method, data should always be read and written directly through instance variables.

  3. Data configured with Lazy Initialization should be read through properties.

  4. Do not invoke the setter/getter method in the setter/getter method.

Posted by Patch^ on Tue, 15 Oct 2019 06:51:31 -0700