美文网首页
iOS 学习笔记集合

iOS 学习笔记集合

作者: 93b3d3ccb7e6 | 来源:发表于2019-12-02 12:27 被阅读0次

    一、对象属性

    对于具有可变副本的属性 (NSArrayNSStringNSDictionary),我们倾向于将其声明为 copy

    比如说,我们定义 Person 对象的 name 属性的类型是 NSString,有可能有人创建了一个 Person 对象,并且给这个属性赋了一个 NSMutableString 的名字值 tempName

    然后过了一会儿,这个可变字符串 tempName 被变更了。

    如果我们的属性不是 copy 而是 strong 的话,随着可变字符串 tempName 的改变,我们的 Person 对象也将发生改变,这不是我们希望发生的。

    例子如下:

    @interface Student : NSObject
    
    @property (copy, nonatomic) NSString *name;
    //@property (strong, nonatomic) NSString *name;
    
    @end
    
    
    - (void)testStudent{
        
        //1.定义一个可变字符串 
        NSMutableString *tempName = [NSMutableString stringWithFormat:@"zhangsan"];
        
        //2.创建 Student 对象并给 name 赋值
        Student *student = [[Student alloc] init];
        student.name = tempName;
        
        //3.修改字符串
        [tempName appendString:@"22"];
     
        NSLog(@"1 tempName:%p - name:%p", tempName, student.name);
        NSLog(@"2 tempName:%@ - name:%@", tempName, student.name);
    }
    

    使用 strong 修饰 name 时的输出如下:

    1 tempName:0x60000147f360 - name:0x60000147f360
    2 tempName:zhangsan22 - name:zhangsan22
    

    使用 copy 修饰 name 时的输出如下:

    1 tempName:0x600000af8a20 - name:0xd3c6a2453c0e238f
    2 tempName:zhangsan22 - name:zhangsan
    

    二、不可变对象

    如果我们需要的是不可变对象,那么我们要确保它在被创建后就不能再被更改。

    我们可以通过使用初始化方法并且在接口中将我们的属性声明为 readonly 来实现这一点。

    @interface Person : NSObject<NSCopying>
    
    @property (readonly, nonatomic) NSString *name;
    @property (readonly, nonatomic) NSDate *birthDate;
    @property (readonly, nonatomic) NSInteger age;
    
    - (instancetype)initWithName:(NSString *)name birthDate:(NSDate *)birthDate age:(NSInteger)age;
    
    @end
    
    #import "Person.h"
    
    @implementation Person
    
    - (instancetype)initWithName:(NSString *)name birthDate:(NSDate *)birthDate age:(NSInteger)age{
        
        if (self = [super init]) {
            _name = [name copy]; 
            _age = age;
            _birthDate = birthDate;
        }
        return self;
    }
    
    @end
    

    现在我们构建新的 Person 对象和其他的类一起工作的时候,我们知道 Person 的 name 这些值是不会发生改变的。

    注意:在 Person 的初始化方法或者是 dealloc 中最好使用实例变量而不要使用属性,因为你无法确定 self 调用的到底是不是你想要的实例。


    三、消息传递机制

    消息传递中的发送者、接收者举例:我们创建的 table view 是发送者,而它的 delegate 则是接收者。

    1.NSNotification

    通知的独特之处在于,发送者和接收者不需要相互知道对方,所以通知可以被用来在不同的相隔很远的模块之间传递消息。

    使用场景:

    • 如果要在项目的两个不相关的模块中传递消息时,通知机制是非常好的工具。

    2.Delegation

    如果使用 delegation 模式的话,发送者需要知道接收者,但是反过来没有要求。

    使用场景:

    • 如果只要在相对接近的两个模块间传递消息,delegation 是很灵活很直接的消息传递机制。

    3.KVO

    KVO 是提供对象属性被改变时的通知的机制。

    使用场景:

    • 如果只对某个对象的值的改变感兴趣的话,就可以使用 KVO 消息传递。

    使用前提:

    • 1.接收者(接收对象改变的通知的对象)需要知道发送者 (值会改变的对象)。
    • 2.接收者需要知道发送者的生命周期,因为它需要在发送者被销毁前注销观察者身份。

    4.Block

    使用场景:

    • 如果一个被调用的方法需要发送一个一次性的消息作为回复,那么使用 block 是很好的选择。
    • 如果要将处理的消息和对消息的调用放在一起来增强可读性的话,也可以使用 block。

    注意:为了不出问题,我们需要保证编码器对象在某个时间点会释放对 block 的引用。
    一旦任务完成,completion block 调用过了以后,我们就应该把它设为 nil。

    5.Target-Action

    Target-Action 消息的接收者不知道消息的发送者,并且消息的发送者也不知道消息的接收者。

    使用场景:

    • Target-action 机制非常适合响应 UI 的事件,没有其他的消息传递机制能够提供相同的功能。

    注意:如果 target 是明确指定的,那么 action 消息会发送给指定的对象。
    如果 target 是 nil, action 消息会一直在响应链中被传递下去,直到找到一个能处理它的对象。


    四、weak singleton 及使用场景

    weak singleton 实现如下:

    @implementation WeakSingleton
    
    + (instancetype)sharedInstance{
        static __weak WeakSingleton *instance;
        WeakSingleton *strongInstance = instance;
        
        @synchronized (self) {
            if (strongInstance == nil) {
                strongInstance = [[[self class] alloc] init];
                instance = strongInstance;
            }
        }
        return strongInstance;
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone{
        static __weak WeakSingleton *instance;
        WeakSingleton *strongInstance = instance;
        
        @synchronized (self) {
            if (strongInstance == nil) {
                strongInstance = [super allocWithZone:zone];
                instance = strongInstance;
            }
        }
     
        return strongInstance;
    }
    
    - (id)copyWithZone:(NSZone *)zone{
        return [WeakSingleton sharedInstance];
    }
    
    - (void)dealloc{
        NSLog(@"-->> %s", __FUNCTION__);
    }
    
    @end
    

    使用场景:
    weak singleton 能在不同的地方访问同一个对象,如下图:

    image.png

    相关文章

      网友评论

          本文标题:iOS 学习笔记集合

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