标题这几个概念对于我这个从android过来的人真可谓是新鲜啊,但这恰恰又是Objective-c的重点,如果能很好的理解这几个概念相信会对Objective-c底层有更深层次的理解,而不只是停留在一般开发上,就算是面试也好跟技术官侃侃而谈。
首先是BOOL,这个比较好理解只要知道Objective-c中,BOOL和bool是不一样的就好了,BOOL是Objective-c的。我们再看看BOOL在objc.h这个文件里面是怎么定义的。
/// Type to represent a boolean value.
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
所以从本质上来说BOOL是一个8bit的一个char,所以我们在把其他比如说short或者int转换成为BOOL的时候一定要注意。如果short或者int的最低的8位bit都是0的话,尽管除了最低的8位以外都不是0,那么经过转换之后,就变成了0也就是NO。还有就是Objective-C里面的所有的逻辑判断例如if语句等等和C语言保持兼容,如果数值不是0判断为真,如果数值是0那么就判断为假,并不是说定义了BOOL值之后就变成了只有1或者YES为真。
一开始我看到上面的定义我也不是太理解低8位是啥,后来我查了下其实就是大学里最最基础的知识而已,当初听课不深入,忘了,现在补一下。
网上很喜欢用256这个十进制的数来做例子,我也用这个吧。
首先256这个数字如果换成16位2进制就是0000 0001 0000 0000.这里高八位其实就是0000 0001,低八位是0000 0000.那么按照之前的知识如果把256赋给一个BOOL的话,那么这个BOOL就是NO了。很好理解吧~
PS:如果直接在代码中写if(256)这样的话是走C的判断,是YES而不是NO。
接下来就是SEL,其实在Objective-c中,每个方法都对应一个唯一的ID值,这个ID标示其实就是SEL。在开发中经常会遇到如下代码:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
这里的action:(SEL)action就是要传一个类型为SEL的变量进去了。然后方法根据这个SEL去查找ID,找到了就可以发送消息了。这样的机制大大的增加了我们的程序的灵活性,我们可以通过给一个方法传递SEL参数,让这个方法动态的执行某一个方法;我们也可以通过配置文件指定需要执行的方法,程序读取配置文件之后把方法的字符串翻译成为SEL变量然后给相应的对象发送这个消息。
在开发中经常使用@selector()来获取一个SEL变量,@selector()其实是一个编译器指令,它把凡是在括号内的都认定为是一个SEL类型。
说到SEL不得不说一下IMP,那SEL和IMP有什么不同呢?IMP是一个函数指针,而虽然每一个SEL对应的是一个方法的名称,但考虑到效率,SEL本身是一个整型,编译器会另外生成一张SEL和方法名称对应的表。有了这样的结构,objc就可以实现多态了。所以IMP的效率是最高的。
typedef id (*IMP)(id, SEL, ...);
最后就是isa了,先附上图上isa的定义
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif
通过后台输出的结果是:Printing description of myOwn->isa:MyOwn
在NSObject里面是这么定义objc_class的
typedef struct objc_class *MetaClass;
typedef struct objc_class *Class;
struct objc_class {
MetaClass class_pointer;
struct objc_class* super_class;
const char* name;
long version;
unsigned long info;
long instance_size;
struct objc_ivar_list* ivars;
struct objc_method_list* methods;
struct sarray * dtable;
struct objc_class* subclass_list;
struct objc_class* sibling_class;
struct objc_protocol_list *protocols;
void* gc_object_type;
};
isa本质是一个指针,这个指针也是NSObject的唯一变量,通过这个isa计算偏移可以找到其他实例变量的位置。
暂时理解就那么多~希望再深入可以继续了解更多,不过了解这些知识已经是举步维艰了。