美文网首页
《Effective Objective-C 2.0 》 阅读笔

《Effective Objective-C 2.0 》 阅读笔

作者: dibadalu | 来源:发表于2016-03-18 15:06 被阅读44次

第18条:尽量使用不可变对象

  • 尽量把对外公布出来的属性设为只读,而且只在确有必要时才将属性对外公布。
  • 对象中表示各种collection的那些属性,通常情况下,提供一个readonly属性供外界使用,该属性将返回一个不可变的collection,而此collection则是内部那个可变collection的一份拷贝。
  • 强调:不要在返回的对象上查询类型以确定是否可变。

例子

EOCPerson类

/* EOCPerson头文件 */
#import <Foundation/Foundation.h>

@interface EOCPerson : NSObject

@property(nonatomic ,copy, readonly) NSString *firstName;
@property(nonatomic ,copy, readonly) NSString *lastName;
@property(nonatomic ,strong, readonly) NSSet *friends; // 不可变set
- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName;
- (void)addFriend:(EOCPerson *)person;
- (void)removeFriend:(EOCPerson *)person;
@end

#import "EOCPerson.h"

@interface EOCPerson ()
// 改为readwrite属性
@property(nonatomic ,copy, readwrite) NSString *firstName;
@property(nonatomic ,copy, readwrite) NSString *lastName;

@end

/* EOCPerson实现文件 */
@implementation EOCPerson
{// 实例变量
    NSMutableSet *_internalFriends; // 可变set
}

- (NSSet *)friends{
    return [_internalFriends copy]; // 拷贝一份不可变的set
}

- (void)addFriend:(EOCPerson *)person{
    [_internalFriends addObject:person];
}

- (void)removeFriend:(EOCPerson *)person{
    [_internalFriends removeObject:person];
}

- (id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName{
    if (self = [super init]) {
#warning 不需要再copy一份
        _firstName = firstName;
        _lastName = lastName;
        _internalFriends = [NSMutableSet new]; // 延迟初始化
    }
    return self;
}

// 覆写description方法
- (NSString *)description{
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
@end

main函数

#import <Foundation/Foundation.h>
#import "EOCPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 1.创建3个EOCPerson对象
        EOCPerson *person = [[EOCPerson alloc] initWithFirstName:@"Bob" andLastName:@"Simth"];
        NSLog(@"person = %@ %@", person.firstName, person.lastName);
        
        EOCPerson *person2 = [[EOCPerson alloc] initWithFirstName:@"Bill" andLastName:@"Jobs"];
        NSLog(@"person2 = %@ %@", person2.firstName, person2.lastName);
        
        EOCPerson *person3 = [[EOCPerson alloc] initWithFirstName:@"Jane" andLastName:@"Galloway"];
        NSLog(@"person3 = %@ %@", person3.firstName, person3.lastName);
        
        // 2.通过addFriend:方法给person添加2个朋友(person2&person3)
        [person addFriend:person2];
        [person addFriend:person3];
        NSLog(@"the friends of person = %@", person.friends);
        
    }
    return 0;
}

输出结果:

Snip20160318_30.png

要点

  • 尽量创建不可变的对象
  • 若某属性仅可于对象内部修改,则在“class-continue分类”中将其由readonly属性扩展为readwrite属性
  • 不要可变的collection作为属性公开,而应提供相关方法,以此修改对象中的可变collection。

相关文章

网友评论

      本文标题:《Effective Objective-C 2.0 》 阅读笔

      本文链接:https://www.haomeiwen.com/subject/dwthlttx.html