首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Learn Objective C(四)Programming with Objective-C - Encapsulating Data and Custom

2013-10-23 
Learn Objective C(4)Programming with Objective-C - Encapsulating Data and CustomLearn Objective C(4

Learn Objective C(4)Programming with Objective-C - Encapsulating Data and Custom

Learn Objective C(4)Programming with Objective-C - Encapsulating Data and Customizing Existing Classes

3. Encapsulating Data
3.1 Properties Encapsulate an Object's Values
Declare Public Properties for Exposed Data
@interface ZJUPerson : NSObject
@property NSString *firstName
@property NSString *lastName
@end

Use Accessor Methods to Get or Set Property Values
NSString *firstName = [somePerson firstName];
[somePerson setFirstName:@"Carl"];

By default, these accessor methods are synthesized automatically for you by the compiler.

@property (readonly) NSString *fullName;

The opposite of readonly is readwrite, it is default.

@property (getter=isFinished) BOOL finished;
@property (readonly, getter=isFinished) BOOL finished;

Dot Syntax Is a Concise Alternative to Accessor Method Calls
NSString *firstName = somePerson.firstName;
somePerson.firstName = @"Carl";

Getting a value using somePerson.firstName is the same as using [somePerson firstName]
Setting a value using somePerson.firstName = @"Carl" is the same as using [somePerson setFirstName: @"Carl"];

Most Properties Are Backed by Instance Variables
For a property called firstName, the synthesized instance variable will be called _firstName.
- (void) someMethod {
? ? ?NSString *myString = @"an string";
? ? ?_someString = myString;
}

_someString is an instance variable.

- (void) someMethod {
? ? ?NSString *myString = @"an string";
? ? ?self.someString = myString;
}

You can Customize Synthesized Instance Variable Names
@implementation YourClass
@synthesize propertyName = instanceVariableName;
…snip…
@end

The default is @synthesize firstName = firstName;

But we should always use
@synthesize firstName = _firstName;

You Can Define Instance Variables without Properties
It is best practice to use a property on an object any time you need to keep track of a value.
If we want to define our own instance variables without declaring a property, we can add them insides braces at the top of the class interface or implementation.

@interface SomeClass : NSObject {
? ? ?NSString *_myNonPropertyInstanceVariable;
}
@end

@implementation SomeClass {
? ? ?NSString *_anotherCustomInstanceVariable;
}
@end

Access Instance Variables Directly from Initializer Methods
Creating the initialize methods.
- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *) aLastName;

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *) aLastName {
? ? ?self = [super init];
? ? ?if(self){
? ? ? ? ? _firstName = aFirstName;
? ? ? ? ? _lastName = aLastName;
? ? ?}
? ? ?return self;
}

The Designated Initializer is the Primary Initialization Method
We need to define one designated initializer among a lot of initialization methods.

You Can Implement Custom Accessor Methods
@property (readonly) NSString *fullName;
- (NSString *) fullName {
? ? ?return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

Properties Are Atomic by Default
@interface ZJUObject : NSObject
@property NSObject *firstObject; ? //atomic by default
@property (atomic) NSObject *secondObject //
@end

From different threads, it is always fully retrieved by the getter method or fully set via the setter method.

atomic -- nonatomic
@interface ZJUObject : NSObject
@property (nonatomic) NSObject *oneobject;
@end

@implementation ZJUObject
- (NSObject *) oneobject {
? ? ?return _oneobject;
}
//setter will be synthesized automatically
@end

3.2 Manage the Object Graph through Ownership and Responsibility
In Objective-C, an object is kept alive as long as it has at least one strong reference to it from another object.
ZJUPerson Object
@property NSString *firstName; ? ? -----strong -----> NSString Object @"Carl"
@property NSString *lastName; ? ? ------strong -----> NSString Object @"Luo"

Avoid Strong Reference Cycles
If a group of objects is connected by a circle of strong relationships, they keep each other alive even if there are no strong references from outside the group.

A strong reference circle
NSTableView ? ? ? ? ? ? -------> strong ------> Delegate Object
@property id delegate <------- strong -------- @property NSTableView *tableView;

NSTableView ? ? ? ? ? ? ? ? ? ? ? ?-------> weak ------> Delegate Object
@property (weak) id delegate <------- strong -------- @property NSTableView *tableView;

Use Strong and Weak Declarations to Manage Ownership
By default the references are strong
@property id delegate;

@property (weak) id delegate;

Local variables also maintain strong references to objects by default. If we don't want a variable to maintain a strong reference, we can declare __weak
NSObject *__weak weakVariable;

Use Unsafe Unretained References for Some Classes
@property (unsafe_unretatined) NSObject *unsafeProperty;
NSObject * __unsafe_unretained unsafeReference;

Copy Properties Maintain Their Own Copies
@interface ZJUBadgeView : NSView
@property NSString *firstName;
@property NSString *lastName;
@end

NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.badgeView.firstName = nameString;

nameString appendString:@"ny";

The object ZJUBadgeView will change after the append action. So we need a copy of the value for the object in some circumstances.
@interface ZJUBadgeView : NSView
@property (copy) NSString *firstName;
@property (copy) NSString *lastName;
@end

alternatively

- (id) initWithSomeOriginalString:(NSString *) aString {
? ? ?self = [super init];
? ? ?if (self) {
? ? ? ? ? _instanceVariableForCopyProperty = [aString copy];
? ? ?}
? ? ?return self;
}

4. Customizing Existing Classes
4.1 Categories Add Methods to Existing Classes
@interface ClassName (CategoryName)

@end

At runtime, there is no difference between a method added by a category and one that is implemented by the original class.

Write the Category for ZJUPerson class like this.
#import "ZJUPerson.h"

@interface ZJUPerson (ZJUPersonNameDisplayAddtions)
? ? ?- (NSString *) lastNameFirstNameString;
@end

A category is usually declared in a separate header file and implemented in a separate source code file. For example
ZJUPerson+ZJUPersonNameDisplayAdditions.h

The category implementation is as follow:
#import "ZJUPerson+ZJUPersonNameDisplayAdditions.h"

@implementation ZJUPerson ( ZJUPersonNameDisplayAdditions)
? ? ?- (NSString *) lastNameFirstNameString {
? ? ? ? ? return [NSString stringWithFormat: @"%@, %@", self.lastName, self.firstName];
? ? ?}
@end

After implement the Category, we can use that method both in ZJUPerson class itself or the sub classes.

#import "ZJUPerson+ZJUPersonNameDisplayAdditions.h"

@implementation SomeObject
? ? ?- (void) someMethod {
? ? ? ? ? ZJUPerson *person = [[ZJUPerson alloc] initWithFirstName:@"Carl"
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastname:@"Luo"];
? ? ? ? ? NSLog(@"The people is %@", [person lastnameFirstNameString]);
? ? ?}
@end

We can provide different implementations for the category methods, depending on whether I am writing an app for OS X or iOS.

Avoid Category Method Name Clashes
We need to be very careful about method names, if the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.

To solve the clashes, it is best practice to add a prefix to the method name.
+ (id) zju_sortDescriptorWithKey: (NSString *) key ascending: (BOOL) ascending;

4.2 Class Extensions Extend the Internal Implementation
A class extension bears some similarity to a category, but it can only be added to a class for which you have the source code at compile time.
There is no way to declare a class extension on a framework class.

@interface ClassName ()
@end

Since there is not name in the parentheses, class extensions are often referred to as anonymous categories. We can define the properties then.
@interface ZJUPerson ()
? ? ?@property NSObject *extraProperty;
@end

Use Class Extensions to Hide Private Information
…snip...

Consider Other Alternatives for Class Customization
…snip...


References:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW1




热点排行