1. @porpertyIntroduction to the

Properties in Objective-C are defined by using @property. Such as:

@property (readonly.getter=isBlue) BOOL blue;
Copy the code

Property captures the state of an object. They reflect the intrinsic attributes of an object and its relationship to other objects. Properties provide a safe and convenient way to interact with these attributes without having to manually write a series of access methods, and customize getters and setters if necessary to override the related methods automatically generated by the compiler.

Use properties rather than instance variables as often as possible, because properties have many advantages over instance variables:

  • Automatic synthesisgetterandsetterMethods. When a property is declared, the compiler automatically generates it by defaultgetterandsettermethods
  • Better declare a set of methods. This is clear because of the naming convention of the access methodsgetterandsetterThe use of.
  • The property keyword can convey additional information about the behavior. Properties provide a number of features that you might use to make a declaration, includingassign.copy.weak.strong.atomic.nonatomic.readwrite.readonlyAnd so on.

2. @propertyusage

1. Manually define instance variables

Manually define instance variables, and manually create getters and setters for the variables:

@interface Person : NSObject {
    NSString *_name;
    NSUInteger _age;
}
// Declare the getter and setter methods in the.h file.
- (void)setName:(NSString*)name;
- (NSString*)name;
- (void)setAge:(NSUInteger)age;
- (NSUInteger)age;
@end

@implementation Person
// Implement the getter and setter methods in the.m file.
Getters and setters are essentially instance methods that conform to certain naming conventions.
- (void)setName:(NSString*)name {
    _name = [name copy];
}
- (NSString*)name {
    return _name;
}
- (void)setAge:(NSUInteger)age {
    _age = age;
}
- (NSUInteger)age {
    return _age;
}
@end
Copy the code
int main(int argc, const char * argv[]) {

    Person *p = [[Person alloc] init];
    [p setName:@"XXXX"]; //p.name = @"XXX";
    [p setAge:20]; 	 //p.age = 20;
    NSLog(@"%@ %ld", [p name], [p age]);// NSLog(@"% @% ld", p.name, p.age);
    //Objective-C allows you to use dot syntax to access methods.
    // The dot-syntax approach essentially calls the setters and getters that we created manually.
    
    return 0;
}
Copy the code

2. Use@propertyDeclaration attributes

1. @property

Declare two properties name and age using @property and automatically generate the declaration of getter and setter methods for the properties (before Xcode4.5) :

@interface Person : NSObject 

@property  NSString* name;
@property  NSUInteger age;

@end

@implementation Person
- (void)setName:(NSString*)name {
    _name = [name copy];
}
- (NSString*)name {
    return _name;
}
- (void)setAge:(NSUInteger)age {
    _age = age;
}
- (NSUInteger)age {
    return _age;
}
@end
Copy the code

2. @synthesize

At sign synthesize is a compiler directive that automatically generates (by default) private instance variables named _name and _age for these two properties (generated in a.m file) to store the properties, Getters and setters for properties are automatically generated. You can also customize getters and setters to override the compiler’s default generated methods, just as you can manually create getters and setters.

@interface Person : NSObject

@property (nonatomic.copy) NSString* name;
@property (nonatomic.assign) NSUInteger age;

@end

@implementation Person

@synthesize name = _name;
@synthesize age = _age;

@end
/* @synthesize age = _age; The compiler automatically generates and uses the instance variable (_age) to store the age property at compile time. _age has nothing to do with age, but getters and setters can be accessed using the name and age dot syntax when the two properties are used at the top level. If you don't want to automatically generate and use the default instance variable to store the age attribute, you can name it anything you want, but it's best to use the official naming rules; @synthesize age = XXXX; The compiler will automatically generate it at compile time and use this instance variable XXXX to store the age property @synthesize age; Instead of telling the system to whom to assign the passed value, the compiler generates it at compile time and stores the age */ in an instance variable with the same name as the property
Copy the code

Use 3.@property(enhanced) declare attributes

Xcode4.5 later declares properties with @property, which automatically does three things

  • H: declaring attributesgetterandsetterMethods;
  • M: Implementation propertiesgetterandsetterMethods;
  • M: declare a private instance variable (default :_ attribute name);

3. @propertyThe modifier

Declare two properties name and age with @Property and set some indicators for them.

@interface Person : NSObject

@property (nonatomic.copy) NSString* name;
@property (nonatomic.assign) NSUInteger age;

@end
Copy the code

When a property is declared, there are usually several indicators. Indicators include:

  1. Atomicity:atomic / nonatomic
  2. Access:readwrite / readonly
  3. Storage(memory management feature):strong / weak / assign / copy / retain
  4. getter = XXX / setter = XXX
  5. Nullability: nullable / nonnul / null_unspecified / null_resettable

1. The atomicity

1. atomic

The default property, to some extent thread-safe, is that all atomic does is lock getters and setters. That is, one thread is accessing the setter, and the other threads have to wait until it’s done.

2. nonatomic

There is no guarantee that you will get a valid value, and if, as described above, both read and write threads access the variable at the same time, it may give you a garbage value that is meaningless. Because atomic is not fully thread-safe at the program level and has additional performance costs, all Settings use nonatomic to improve access performance. The essential difference between atomic and nonatomic is the operation on the setter method.

2. Access features

3. readwrite

The compiler automatically generates getters and setters for the default properties.

4. readonly

The compiler only generates setters for properties. In addition, you can use readonly in a.h file and readwrite in a.m file class extension to prevent outsiders from tampering with the property.

3. Memory management feature

5. strong

The default value of the ARC attribute, which indicates that the attribute has a strong reference to the assigned value and will retain the new value (increasing its reference count) before releasing the old value (decreasing its reference count). You can only decorate objects.

6. copy

Prevents properties from being modified. In shallow copy, the attribute increases the reference count of the assigned value. In deep copy, it does not increase the reference count of the assigned value, and then releases the old value, which reduces the reference count of the old value. Usually used to decorate an object that has a mutable type subclass. Such as: nsstrings, NSArray, NSDictionary, etc.

For mutable object types, such as NSMutableString and NSMutableArray, copy is not allowed. Since these classes implement the NSCopying protocol, the copy method returns immutable objects, so use: strong.

Copy is also used to refer to a block. In ARC, copy is used by default. Normally, a block is allocated in the heap when it needs to capture external data, but in MRC environments, because of manual reference counting, blocks are usually allocated in the stack. You need to copy to the heap to prevent wild pointer errors.

7. weak

This property holds a weak reference to the assigned value object. It does not increase the reference count of the new value assigned or decrease the reference count of the old value, but when the value is destroyed, the weak attribute is automatically assigned to nil, thus avoiding wild pointer errors. You can only decorate objects.

8. assign

Default value of MRC attribute. Simple assignment is performed on the attribute without changing the reference count of the new value assigned or the old value assigned. Often used for base types. You can also decorate an object, and when the object is destroyed, the compiler does not set this property to nil(producing an wild pointer).

9. unsafe_unretained

A simple assignment to a property does not change the reference count of the new value assigned, nor does it change the reference count of the old value, and the compiler does not set the property to nil(producing an wild pointer) when the object is destroyed. You can only decorate objects.

10. retain

MRC features. Indicates that the attribute will retain the new value, increasing the reference count of the new value, and then release the old value, decreasing the reference count of the old value. You can only decorate objects.

4. Rename the access method

11. setter

12. getter

// We always change the name of the getter method to isXXX when we get the value of a property of type BOOL
@property ( getter = isBlue) BOOL blue;

// Access methods cannot start with new. If you want to name a property that starts with new, a new getter will be generated by default:
Property follows Cocoa naming convention for RETURNING 'owned' objects.
// Rename the getter method with getter =
@property (nonatomic.copy.getter= theNewName,setter = XXX) NSString *newName;
Copy the code

5. Is empty

In iOS9 Xcode 6.3, Objective-C has added a language feature called NullAbility in order to better mix with Swift (with Swift optional). Specifically, the following four new features.

13. nonnull

Indicates that the property cannot be empty.

Nullable are in the minority of interfaces, so to prevent writing a lot of Nonnulls, Foundation provides a pair of macros. Objects wrapped in macros are nonnull by default, and nullable properties are added manually if they are nullable.

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject

@property (nonatomic.copy) NSString *name1;
@property (nonatomic.assign) NSUInteger age;

@property (nonatomic.copy.nullable) NSString *name2;
/ / equivalent
@property (nonatomic.copy) NSString *_Nullable name2;

@end
  
NS_ASSUME_NONNULL_END
Copy the code

14. nullable

Indicates that the property can be null.

15. null_resettable

Indicates that the property setter parameter value is nullable and the getter return value is nonable. That is, setters can be null and getters cannot be null (for example, null_resettable is used when some properties provide a default value). You have to override one of the setters or getters, make your own judgment, and make sure that the value that’s actually returned is not nil. Otherwise, a warning is reported: Synthesized setter ‘setName:’ for NULl_resettable property ‘name’ does not handle nil

16. null_unspecified

Property default value, indicating that the property is unsure whether to be empty.