美文网首页
09-Runtime01

09-Runtime01

作者: weyan | 来源:发表于2019-03-11 13:16 被阅读0次

    一、设置取值

    • 1、 把三个变量的值存储在一个字节中
    ------------------------------------MJPerson.h-----------------------------------
    #import <Foundation/Foundation.h>
    
    @interface MJPerson : NSObject
    //@property (assign, nonatomic, getter=isTall) BOOL tall;
    //@property (assign, nonatomic, getter=isRich) BOOL rich;
    //@property (assign, nonatomic, getter=isHansome) BOOL handsome;
    
    - (void)setTall:(BOOL)tall;
    - (void)setRich:(BOOL)rich;
    - (void)setHandsome:(BOOL)handsome;
    
    - (BOOL)isTall;
    - (BOOL)isRich;
    - (BOOL)isHandsome;
    
    @end
    
    ------------------------------------MJPerson.m-----------------------------------
    #import "MJPerson.h"
    
    // &可以用来取出特定的位
    
    // 0000 0111
    //&0000 0100
    //------
    // 0000 0100
    
    /** 掩码,一般用来按位与(&)运算的 **/
    //#define MJTallMask 1 //0b00000001
    //#define MJRichMask 2 //0b00000010
    //#define MJHandsomeMask 4 //0b00000100
    
    //#define MJTallMask 0b00000001
    //#define MJRichMask 0b00000010
    //#define MJHandsomeMask 0b00000100
    
    //1往左移动0位(0b00000001)
    #define MJTallMask (1<<0)
    //1往左移动1位(0b00000010)
    #define MJRichMask (1<<1)
    //1往左移动2位(0b00000100)
    #define MJHandsomeMask (1<<2)
    
    @interface MJPerson()
    {
        char _tallRichHansome;
    }
    @end
    
    @implementation MJPerson
    
    
    // 0010 1010
    //&1111 1101
    //----------
    // 0010 1000
    
    - (instancetype)init
    {
        if (self = [super init]) {
            _tallRichHansome = 0b00000100;
        }
        return self;
    }
    
    - (void)setTall:(BOOL)tall
    {
        if (tall) {
            _tallRichHansome |= MJTallMask;
            //相当于按位取或_tallRichHansome = _tallRichHansome | MJTallMask;
        } else {
            //~按位取反(例如:0b00001010 按位取反后为 0b11110101)
            _tallRichHansome &= ~MJTallMask;
        }
    }
    
    - (BOOL)isTall
    {
        return !!(_tallRichHansome & MJTallMask);
        //(_tallRichHansome & MJTallMask)如果这位结果为1,那么!为假,再!为真,和原来保持一样。
    }
    
    - (void)setRich:(BOOL)rich
    {
        if (rich) {
            _tallRichHansome |= MJRichMask;
        } else {
            _tallRichHansome &= ~MJRichMask;
        }
    }
    
    - (BOOL)isRich
    {
        return !!(_tallRichHansome & MJRichMask);
    }
    
    - (void)setHandsome:(BOOL)handsome
    {
        if (handsome) {
            _tallRichHansome |= MJHandsomeMask;
        } else {
            _tallRichHansome &= ~MJHandsomeMask;
        }
    }
    
    - (BOOL)isHandsome
    {
        return !!(_tallRichHansome & MJHandsomeMask);
    }
    
    @end
    
    -------------------------------------main.m---------------------------------------
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            MJPerson *person = [[MJPerson alloc] init];
    //        person.rich = YES;
    //        person.tall = NO;
    //        person.handsome = NO;
            
            NSLog(@"tall:%d rich:%d hansome:%d", person.isTall, person.isRich, person.isHandsome);
            
    //        NSLog(@"%zd", class_getInstanceSize([MJPerson class]));
        }
        return 0;
    }
    

    二、位域

    • 2、设置取值采用第二种方案:位域(可读性较好)
    ------------------------------MJPerson.h-----------------------------
    #import <Foundation/Foundation.h>
    
    @interface MJPerson : NSObject
    //@property (assign, nonatomic, getter=isTall) BOOL tall;
    //@property (assign, nonatomic, getter=isRich) BOOL rich;
    //@property (assign, nonatomic, getter=isHansome) BOOL handsome;
    
    - (void)setTall:(BOOL)tall;
    - (void)setRich:(BOOL)rich;
    - (void)setHandsome:(BOOL)handsome;
    
    - (BOOL)isTall;
    - (BOOL)isRich;
    - (BOOL)isHandsome;
    
    @end
    ---------------------------------------MJPerson.m-----------------------------------
    #import "MJPerson.h"
    
    //#define MJTallMask (1<<0)
    //#define MJRichMask (1<<1)
    //#define MJHandsomeMask (1<<2)
    
    @interface MJPerson()
    {
        // 结构体支持位域
        struct {
            char tall : 1;//1:只占一位
            char rich : 1;
            char handsome : 1;
        } _tallRichHandsome;//结构体类型的成员变量_tallRichHandsome(这个结构体只有一个字节)
    }
    @end
    
    @implementation MJPerson
    
    - (void)setTall:(BOOL)tall
    {
        _tallRichHandsome.tall = tall;
    }
    
    - (BOOL)isTall
    {
        return !!_tallRichHandsome.tall;
    }
    
    - (void)setRich:(BOOL)rich
    {
        _tallRichHandsome.rich = rich;
    }
    
    - (BOOL)isRich
    {
        return !!_tallRichHandsome.rich;
    }
    
    - (void)setHandsome:(BOOL)handsome
    {
        _tallRichHandsome.handsome = handsome;
    }
    
    - (BOOL)isHandsome
    {
        return !!_tallRichHandsome.handsome;
    }
    
    @end
    
    -------------------------------------main.m-----------------------------------
    #import <Foundation/Foundation.h>
    #import "MJPerson.h"
    #import <objc/runtime.h>
    
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            MJPerson *person = [[MJPerson alloc] init];
            person.rich = YES;
            person.tall = NO;
            person.handsome = NO;
            
            NSLog(@"tall:%d rich:%d hansome:%d", person.isTall, person.isRich, person.isHandsome);
        }
        return 0;
    }
    

    02的十六进制:00000010

    三、共用体

    共用体:共用一块内存。

    ---------------------------------------MJPerson.h---------------------------------------
    #import <Foundation/Foundation.h>
    
    @interface MJPerson : NSObject
    
    - (void)setTall:(BOOL)tall;
    - (void)setRich:(BOOL)rich;
    - (void)setHandsome:(BOOL)handsome;
    - (void)setThin:(BOOL)thin;
    
    - (BOOL)isTall;
    - (BOOL)isRich;
    - (BOOL)isHandsome;
    - (BOOL)isThin;
    
    @end
    ---------------------------------------MJPerson.m------------------------------------------
    #import "MJPerson.h"
    
    #define MJTallMask (1<<0)
    #define MJRichMask (1<<1)
    #define MJHandsomeMask (1<<2)
    #define MJThinMask (1<<3)
    
    @interface MJPerson()
    {
        union {
            int bits;
            
    //        struct {//这个结构体用不到,可以不写,只不过是为了代码可读性
    //            char tall : 4;
    //            char rich : 4;
    //            char handsome : 4;
    //            char thin : 4;
    //        };
        } _tallRichHandsome;
    }
    @end
    
    @implementation MJPerson
    
    - (void)setTall:(BOOL)tall
    {
        if (tall) {
            _tallRichHandsome.bits |= MJTallMask;
        } else {
            _tallRichHandsome.bits &= ~MJTallMask;
        }
    }
    
    - (BOOL)isTall
    {
        return !!(_tallRichHandsome.bits & MJTallMask);
    }
    
    - (void)setRich:(BOOL)rich
    {
        if (rich) {
            _tallRichHandsome.bits |= MJRichMask;
        } else {
            _tallRichHandsome.bits &= ~MJRichMask;
        }
    }
    
    - (BOOL)isRich
    {
        return !!(_tallRichHandsome.bits & MJRichMask);
    }
    
    - (void)setHandsome:(BOOL)handsome
    {
        if (handsome) {
            _tallRichHandsome.bits |= MJHandsomeMask;
        } else {
            _tallRichHandsome.bits &= ~MJHandsomeMask;
        }
    }
    
    - (BOOL)isHandsome
    {
        return !!(_tallRichHandsome.bits & MJHandsomeMask);
    }
    
    
    
    - (void)setThin:(BOOL)thin
    {
        if (thin) {
            _tallRichHandsome.bits |= MJThinMask;
        } else {
            _tallRichHandsome.bits &= ~MJThinMask;
        }
    }
    
    - (BOOL)isThin
    {
        return !!(_tallRichHandsome.bits & MJThinMask);
    }
    
    @end
    
    ---------------------------------------main.m----------------------------------
    #import <Foundation/Foundation.h>
    #import "MJPerson.h"
    #import <objc/runtime.h>
    
    union Date {
        int year;
        char month;
    };
    
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
    //        union Date date;
    //        date.month = 1;
    //        date.year = 2011;
    //
            
            MJPerson *person = [[MJPerson alloc] init];
            person.thin = YES;
            person.rich = YES;
            person.handsome = NO;
            
            NSLog(@"thin:%d rich:%d hansome:%d", person.isThin, person.isRich, person.isHandsome);
        }
        return 0;
    }
    

    总结:

    • 1、类对象、元类对象地址值最后三位一定是0
    • 2、一个十六进制位代表四个二进制位

    相关文章

      网友评论

          本文标题:09-Runtime01

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