• IOS中实例的权限控制


    • @public、@protected、@private的使用

        在OC中声明一个类的时候,可以使用上面 @public、@protected、@private三个关键字声明实例的权限,例如下面的代码:

        

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
    @public
        NSString *_height;
    @protected
        NSString *_weight;
    @private
        NSString *_wife;
    }
    
    @end
    
    
    
    @interface Person ()
    {
        @public
        NSString *_name;
        @protected
        NSString *_sex;
        @private
        NSString *_phoneNO;
    }
    
    - (void)publicMethod;
    
    @end
    
    @implementation Person
    
    
    - (instancetype)init
    {
        if(self = [super init])
        {
            _height = @"1.8m";
            _weight = @"65Kg";
            _wife = @"none";
            _name = @"zhangSan";
            _sex  = @"man";
            _phoneNO = @"1122334455";
        }
        return self;
    }
    
    - (void)publicMethod
    {
        
    }
    
    @end

      在.h文件中定义了三个实例,这三个实例的权限和public、protected、private相对应,对于一个Person类型的对象p,_name在任何地方都是可以访问的,_sex只能在Person

    的子类中访问,_wife只能自己内部访问。在.m文件中定义的三个实例也与public、protected、private相对应,需要注意的是,在其它文件中定义的Person类型的对象p,都不能访问到这三个实例,只有在.m文件内部,public、protected、private才会起到对应的作用。实际上OC中实例的权限控制只是编译时的一种权限限制,在OC runtime的类结构中,实例变量是不存在权限控制的,同样类方法、实例方法也不存在权限控制。

    • 对于KVC来说,无论实例是哪种权限都是可以轻松访问到的,如下面的代码:
    •  @interface Student : Person
      
      @end
      
      
      @implementation Student
      
      
      + (void)testProtected
      {
          Person *p = [Person new];
          NSLog(@"%@",p->_height);
          NSLog(@"%@",p->_weight);
      }
      
      - (NSString *)description
      {
          Person *p = [Person new];
          NSLog(@"%@",p->_height);
          NSLog(@"%@",p->_weight);
      //    NSLog(@"%@",p->_wife);
      //    [p publicMethod];
      //    [self publicMethod];
          //return [NSString stringWithFormat:@"name == %@\nsex == %@\nphone == %@",_name, _sex,_phoneNO]
      //    return [NSString stringWithFormat:@"name == %@\nsex == %@",_name, _sex];
      //    return [NSString stringWithFormat:@"%@ , %@ , %@",_height , _weight ,_wife];
          return [NSString stringWithFormat:@"%@ , %@",_height , _weight];
          
      }
      
      @end

      KVC访问:

    • #import "Other.h"
      #import "Person.h"
      
      @interface Other : NSObject
      
      - (void)testProtected;
      
      - (void)testKVC;
      
      @end
      
      
      @implementation Other
      
      - (void)testProtected
      {
          Person *p = [Person new];
          NSLog(@"%@",p->_height);
      //    NSLog(@"%@",p->_weight);
      }
      
      - (void)testKVC
      {
          Person *p = [Person new];
          NSLog(@"%@",[p valueForKey:@"_name"]);
          NSLog(@"%@",[p valueForKey:@"_sex"]);
          NSLog(@"%@",[p valueForKey:@"_phoneNO"]);
      
          NSLog(@"%@",[p valueForKey:@"_wife"]);
      
      }
      
      @end

      实际KVC读取一个实例变量:

    • - (id)valueForKey: (NSString*)key
      {
          if (!key) {
              id value = [self valueForUndefinedKey:nil];
              return value;
          }
      
          const char *keyCString = [key UTF8String];
          SEL sel = sel_getUid(keyCString);
      
          // FIXME: getKey, _getKey, isKey, _isKey are missing
      
          if ([self respondsToSelector:sel]) {
              id value = [self _wrapReturnValueForSelector:sel];
              return value;
          }
      
          size_t keyCStringLength = strlen(keyCString);
          char *selBuffer = __builtin_alloca(keyCStringLength + 5);
      
          char *keyname = __builtin_alloca(keyCStringLength + 1);
          strcpy(keyname, keyCString);
      
          #define TRY_FORMAT(format)\
                  sprintf(selBuffer, format, keyname);\
                  sel = sel_getUid(selBuffer);\
                  if ([self respondsToSelector:sel]) {\
                      id value = [self _wrapReturnValueForSelector:sel];\
                      return value;\
                  }
          TRY_FORMAT("_%s");
          keyname[0] = toupper(keyname[0]);
          TRY_FORMAT("is%s");
          TRY_FORMAT("_is%s");
      //    TRY_FORMAT("get%s");
      //    TRY_FORMAT("_get%s");
          #undef TRY_FORMAT
      
          if ([isa accessInstanceVariablesDirectly]) {
              sprintf(selBuffer, "_%s", keyCString);
              sel = sel_getUid(selBuffer);
      
              if ([self respondsToSelector:sel]) {
                  id value = [self _wrapReturnValueForSelector:sel];
                  return value;
              }
      
      
              Ivar ivar = class_getInstanceVariable(isa, selBuffer);
              if (!ivar) {
                  ivar = class_getInstanceVariable(isa, keyCString);
              }
      
              if (ivar) {
                  id value = [self _wrapValue:(void*)self + ivar_getOffset(ivar) ofType:ivar_getTypeEncoding(ivar)];
                  return value;
              }
      
          }
      
          id value = [self valueForUndefinedKey:key];
          return value;
      }
  • 相关阅读:
    页面打印
    scala
    IntelliJ Idea 常用快捷键列表
    flume
    spring事务管理方式,aop
    oldboy es和logstash
    elasticsearch视频34季
    elasticsearch视频
    python3
    git
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/4079913.html
Copyright © 2020-2023  润新知