zoukankan      html  css  js  c++  java
  • 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;
      }
  • 相关阅读:
    tensorflow 2.0 学习 (十) 拟合与过拟合问题
    tensorflow 2.0 学习 (九) tensorboard可视化功能认识
    tensorflow 2.0 学习 (八) keras模块的认识
    tensorflow 2.0 学习 (七) 反向传播代码逐步实现
    tensorflow 2.0 学习 (六) Himmelblua函数求极值
    tensorflow 2.0 学习 (五)MPG全连接网络训练与测试
    arp协议简单介绍
    Pthread spinlock自旋锁
    线程和进程状态
    内核态(内核空间)和用户态(用户空间)的区别和联系·
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/4079913.html
Copyright © 2011-2022 走看看