zoukankan      html  css  js  c++  java
  • 【Objective-C学习记录】第二十九天

    内存管理的规则

    1.alloc创建的必须释放,便利构造器创建的不要释放

    2.加入容器中的对象会被执行一次retain操作,引用计数加1

    3.容器移除对象,会向对象发送一次release消息,让对象的引用计数减1

    4.当容器释放的时候,会向容器中的所有对象发送一次release消息

    当进行内存管理时,只要遵循每次增加都对应一次释放就不会出错。下面是一个例子:

    定义一个Hero类,添加如下几个属性和初始化方法:

    1 @property (nonatomic, copy) NSString *name;
    2 @property (nonatomic, assign) NSInteger speed;
    3 @property (nonatomic, retain) NSString *ability;
    4 
    5 - (instancetype)initWithName:(NSString *)name speed:(NSInteger)speed ability:(NSString *)ability;
    6 + (Hero *)heroWithName:(NSString *)name speed:(NSInteger)speed ability:(NSString *)ability;

    在.m文件里一定要设置属性:

    1 @synthesize name = _name;
    2 @synthesize speed = _speed;
    3 @synthesize ability = _ability;

    接着实现初始化方法和销毁方法:

     1  - (void)dealloc
     2 {
     3      //因为speed不是对象类型所以不需要释放内存
     4      [_name release];
     5      [_ability release];
     6      [super dealloc];  
     7  }
     8   
     9  - (instancetype)initWithName:(NSString *)name speed:(NSInteger) speed ability:(NSString *)ability
    10  {
    11       self = [super init];
    12       if (self)
    13       {
    14            _name = name;
    15            _speed = speed;
    16            _ability = ability; 
    17       }
    18       return self;
    19 }
    20  
    21 + (Hero *)heroWithName:(NSString *)name speed:(NSInteger) speed ability:(NSString *)ability
    22 {
    23       return [[[Hero alloc] initWithName:name speed:speed ability:ability] autorelease];
    24 }

    以及setter和getter方法:

     1 - (void)setName:(NSString *)name
     2 {
     3     if(_name != name)
     4     {
     5         [_name release];
     6          _name = [name copy];
     7     }
     8 }    
     9 - (NSString *)name
    10 {
    11     return [[_name retain] autorelease];
    12 }
    13 
    14 - (void)setAbility:(NSString *)ability
    15 {
    16     if(_ability != ability)
    17     {
    18          [_ability release];
    19          _ability = [ability retain];
    20     }
    21 }
    22 - (NSString *)ability
    23 {
    24     return [[ability retain] autorelease];
    25 }

    KVC

    Key Value Coding,键值编码,是一种间接访问实例变量的方法。

    KVC提供了一种使用字符串(key)而不是访问器方法,去访问一个对象实例变量的机制。

    常用方法:

    - (id)valueForKey:(NSString *)key;通过key(实例变量名)获取实例变量的值。

    - (void)setValue:(id)value forKey:(NSString *)key;通过key(实例变量名)给实例变量赋值。

    - (id)valueForKeyPath:(NSString *)keyPath;通过keyPath获取实例变量的值。

    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;通过keyPath给实例变量赋值。

    - (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;将一个字典对象的键值对给对象的各个实例变量赋值。

    注意!当使用KVC时,如果key值和属性名不一样时,就会崩溃。在解决该情况之前,先看看KVC的内部实现过程:

    A.setValue:forKey:(假如给的key是name)

    1.去类里面找是否有一个方法叫setName:,有的话赋值,没有的话执行第二步

    2.去类里面找是否有一个叫_name的实例变量,有的话赋值,没有的话执行第三步

    3.去类里面找是否有一个叫name的实例变量,有的话赋值,没有的话执行第四步

    4.查找当前类是否实现了setValue:forUndefinedKey:方法,如果有,走方法内部实现,如果还没有,就会抛出异常,引起崩溃

    B.valueForKey:(假设给的key是name)

    1.去类里面找是否有一个方法叫getName:,有的话取值,没有的话执行第二步

    2.去类里面找是否有一个叫_name的实例变量,有的话取值,没有的话执行第三步

    3.去类里面找是否有一个叫name的实例变量,有的话取值,没有的话执行第四步

    4.查找当前类是否实现了valueForUndefinedKey:方法,如果有,走方法内部实现,如果还没有,就会抛出异常,引起崩溃

    所以为了防止崩溃情况的发生,只需要重新实现以下setValue:forUndefinedKey:valueForUndefinedKey:这两个方法即可:

    1 - (void)setValue:(id)value forUndefinedKey:(NSString *)key
    2 {
    3 
    4 }
    5 
    6 - (id)valueForUndefinedKey:(NSString *)key
    7 {
    8     return nil;
    9 }

    setValue:forUndefinedKey:方法里可以填充与之相关的操作

  • 相关阅读:
    leetcode4. Median of Two Sorted Arrays
    leetcode5. Longest Palindromic Substring
    leetcode3. Longest Substring Without Repeating Characters
    leetcode1. Two Sum
    leetcode2. Add Two Numbers
    用python slearning类库实现数据挖掘(python3.x)
    hihocoder 1519 : 逃离迷宫II
    hihocoder1524
    Android零基础入门第33节:Android事件处理概述
    Android零基础入门第32节:新推出的GridLayout网格布局
  • 原文地址:https://www.cnblogs.com/shvier/p/5092592.html
Copyright © 2011-2022 走看看