对象、消息、运行期

2017-07-20  本文已影响47人  Mark_Lin

Objective-C作为面向对象编程,“对象”(object)就是“基本构造单元”(building block),开发者可以通过对象来存储并传递数据。

在对象之间传递数据并执行任务的过程就叫做“消息传递”(Messaging)。

第6条:理解“属性”这一概念

第7条:在对象内部尽量直接访问实例变量

第8条:理解“对象等同性”这一概念

==大概的判断逻辑思路如下:==

  1. 首先,直接判断两个指针是否想等(若相等,则其均指向同一个对象,所以受测的对象也必定相等。);
  2. 接下来,比较两对象所属的类(若不属于同一个类,则两对象不相等。);
  3. 但是在继承体系中判断等同性时,经常会遭遇A实例与其子类实例想等,所以实现“isEqual:”方法要考虑到这种情况!
  4. 最后,检测每个属性是否相等。(只要其中有不相等的属性,就判定两对象不等,否则两对象相等。)
  接下来该实现hash方法了,根据等同性约定:若两对象相等,则其哈希码也相等,但是两个哈希码相同的对象却未必相等。这就是能否正确覆写“isEqual:”方法的关键所在。下面这种写法完全可行:

```
- (NSUInteger)hash{
        return 1337;
    }
```

不过若是这么写的话,在collection中使用这种对象将会产生性能问题,因为collection在检索哈希表时,会用对象的哈希码做引索。假如某个collection是用set集合实现的,那么set可能会根据哈希码把对象分装到不同的数组中。在向set中添加新对象的时候,要根据其哈希码找到与之相关的那个数组,依次检查其中各个元素,看数组中已有的对象是否和将要添加的新对象相等。

由此可知,如果令每个对象都返回相同的哈希码,那么在set中已有1 000 000个对象的情况下,若是继续向其中添加对象,则需将这1 000 000个对象全部扫描一遍。

  下面给大家推荐一种技能保持较高效率,又能使生成的哈希码至少位于一定范围内,而不会过于频繁地重复。当然,此算法生成的哈希码还是会碰撞,不过至少可以保证哈希码有多种可能的取值。编写hash方法时,应该用当前的对象做做实验,以便在减少碰撞频度与降低运算复杂程度之间取舍。

```
- (NSUInteger)hash{
    
    NSUInteger firstNameHash = [_firstName hash];
    NSUInteger lastNameHash = [_lastName hash];
    NSUInteger ageHash = _age;
    
    return firstNameHash ^ lastNameHash ^ ageHash;
}
```

set中居然可以包含两个彼此相等的数组!!!根据set语义是不允许出现这种情况的,然而现在却无法保证这一点了,因为我们修改了set中的已有对象。所以,我们得出一个结论:==如果把某对象放入set之后,又修改其内容,那么后面的行为将很难预料==

当然,举这个例子只是为了提醒大家,把某对象加入collection之后,改变其内容将会带来的后果,并没有说绝对不要这么做,而是让大家注意在这样做的时候,要用相应的代码去处理可能出现的问题。

==**要点概括**==
1. 若想检测对象的等同性,请提供“isEqual:”与hash方法;
2. 相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同;
3. 不要盲目地逐个检测每天属性,而是应该依照具体需求来制定检测方法;
4. 编写hash方法时,应该使用计算速度快且哈希码碰撞几率低的算法;

第9条:以“类族模式”隐藏实现细节

第10条:在既有类中使用关联对象存放自定义数据

| 关联类型 | 等效的@property属性 |
| --- | --- |
| OBJC_ASSOCIATION_ASSIGN | assign |
| OBJC_ASSOCIATION_RETAIN_NONATOMIC | nonatomic,retain |
| OBJC_ASSOCIATION_COPY_NONATOMIC | nonatomic, copy |
| OBJC_ASSOCIATION_RETAIN | retain |
| OBJC_ASSOCIATION_COPY | copy |

**下列方法可以管理管理对象:**

第11条:理解objc_msgSend的作用

在Objective-C中,如果向某对象传递消息,那就会使用动态绑定机制来决定需要调用的方法。在底层,所有方法都是普通的C语言函数,然而对象收到消息之后,究竟该调用哪个方法则完全于运行期决定,甚至可以在程序运行时改变,这些特性使得Objective-C成为一门真正的动态语言。

第12条:理解消息转发机制

第13条:用“方法调配技术”调试“黑盒方法”

第14条:理解“类对象”的用意

上一篇 下一篇

猜你喜欢

热点阅读