• 盘点iOS开发中property属性常用关键字


    一、关键字说明

    1、@synthesize:自动生成成员变量相应的存取方法,可以使用点语法操作该变量的存取。

    2、@implementation:  表明类的实现  ,以@end 结束。

    3、self  :类似java语言当中的this ,是隐藏指针  指向接受消息的对象的指针 。消息所调用的方法使用该指针参数查找它要使用的实例。

    4、super : 调用父类的方法 。    self = [ super init];  判断是否可以成功初始化 如果父类成功初始化 那么将会赋值给 self  ,这样self 是一个非空对象。 它不是参数也不是实例变量, 向super 发生消息的时候,实际上是在请求oc向该类的超类 发送请求 ,如果超类中没有定义的消息,oc将按照继承的普通规则在继承链中进行查找。

        继承当中隐藏指针isa  与  super关键字 两张图片来演示:

     

    5、#imoprt  与c语言当中的#include有类似的作用 ,告诉预处理器将头文件的内容包含到本文件的.oc中 ,并且保证头文件只会被包含一次 。

    6、@interface   声明包含一个 XXX 类 ,与@implementation 一样 ,以@end结束。

    7、: 表示继承  后面跟的是父类 。oc是单继承的机制  ,这里跟出c++是不一样的。

    8、@property  关键字   设置成员变量的属性 (读/写    赋值 assign retain copy  ,支持多线程的非原子访问nonatomic)

    二、 方法的声明

      1、 声明一个方法 格式是:

        -(返回值)方法关键字 1 :(参数类型)参数名 方法关键字2 :(参数类型)参数名 ……  (在读方法的时候 ,找方法关键字来确定参数)

      2、-号是实例方法 +号是类方法

      3、另一个初始化的方法中 调用 已有的初始化方法  这种方法被称为是 Designated initializer

    三、输出流

        NSlog是OC中的标准输出 ,附加输出 当时的时间 应用程序的名称 ,使用Nslog()输出任意对象的值时  都会使用%@格式说明 ,在使用这个说明符时  对象通过调用一个名为description的方法提供自己的NSlog()格式

    四、getter / settter 方法

      对象.属性:使用@property配合@synthesize  可以让编译器自动实现 getter/setter方法 ,很方便  可以直接使用”对象 属性“的方法调用

      对象.方法:如果想要调用”对象.方法“的方式来调用一个方法并获取到方法的返回值  需要使用@property配合@dynamic  使用@dynamic 关键字是告诉编译器由我们自己来实现访问方法 。

    五、属性的设置

      1、readonly 此标记说明属性是只读的 ,默认的标记是读写 ,如果指定了制度 在@implementation中只需要一个读取器  或者你使用@synthesize关键字 ,也是有读取器方法被解析 而且如果试图使用点操作符 为 属性赋值 ,那么将会出现编译错误。

      2、readwrite 此标记说明属性会被当成读写的  这也是默认的属性  设置器和读取器都需要在@implementation中实现 ,如果使用@synthesize关键字 读取器和设置器都会被解析

      3、nonatomic 非原子性访问 对于属性赋值的时候不加锁 ,多线程并发访问会提高性能,如果不加此属性 则默认是两个访问方法都为原子型事务访问。

      4、atomic 和 nonatomic用来决定编译器生成的getter和setter是否为原子操作 ,atomic 设置成员变量的@property属性时  默认为是atomic 提供线程安全 。在多线程环境下 ,原子操作是必要的 否则会引起错误的结果 。加了 atomic,setter函数会变成下面这样:

            {lock}

            if(property != newValue){

              [property release];

              property = [newValue retain];

            }

            {unlock}

        nonatomic 禁止多线程,变量保护 提高性能 。atomic 是OC 使用的一种线程保护技术 ,基本上来讲 就是防止在  写   未完成的时候  被另外一个线程读取 ,造成数据错误。而这种机制是耗费系统资源的 ,所以在iPhone这种小型设备上  如果没有使用多线程间的通讯编程  那么 nonatomic是一个非常好的 选择。      访问器是原子操作 ,这也就是说 在多线程环境下,解析的访问器提供一个对属性的安全访问 ,从获取器得到的返回值或者通过设置器设置的值可以一次完成,  即便是别的线程也正在对其进行访问。 如果不指定nonatomic 在自己管理内存的环境中 ,解析的访问器保留并自动释放返回值 ,如果指定了 nonatomic ,那么访问器只是简单的返回这个值。

      5、assign :简单赋值 ,不更改索引计数 ,适用于基础数据类型(NSInteger CGFloat)和C数据类型(int float double char 等)简单数据类型。      此标记说明设置器直接进行赋值 这也是默认值 。在使用垃圾收集的应用程序中,如果要一个属性使用assign ,且这个类符合NSCopying协议 你就要明确指出这个标记 而不是简单的使用默认值 否则的话,将会出现一个编译警告 ,这再次向编译器说明你确实需要赋值 即使它是可拷贝的。

      6、copy :建立一个索引计数为1 的对象 然后释放旧对象  对NSString它指出 ,在赋值时使用传入值的一份拷贝 ,拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。

      7、retain:释放旧对象 将旧对象的值赋予输入对象 ,再提高输入对象的索引计数为1,对其他NSObject和其子类 ,对参数进行release旧值 ,再retain新值,指定retain会在赋值时唤醒传入值的retain消息  此属性只能用于Objective-C对象类型,而不能用于Core Foundation 对象(原因是  retain会增加对象的引用计数 而基本数据类型或者 Core Foundation对象都没有引用计数)

        注:把对象添加到数组中时  引用计数将增加对象的引用次数+1.

        retain 的实际语法为:

      -(void)setName:(NSString*)newName{

        if(name != newName){

          [name release];

          name = [newName retain];//  name's retain count has been retain 1

        }

      }

    8、copy与retain

      1.copy 其实是建立了一个相同的对象 ,而retain不是     比如说 个NSString对象 地址是0x1111 内容为@"STR" ,copy到另外一个NSString之后 ,地址为0x2222 内容相同 新的对象retain 为 1 ,旧有对象没 有变化     ;     retain到另外一个NSString之后,地址相同(建立了一个指针,指针拷贝)内容当然相同  这个对象的retain值+1  也就是说 retain 是指针拷贝   copy 是内容拷贝。

      2.retain的set方法是浅拷贝  copy的set方法是深拷贝

      3.copy的另外一个用法:

      copy是内容拷贝 对于像NSString的确是这样的  但是如果copy的对象是NSArray  

      比如:NSArray*array = [NSArray arrayWithObjects:@"hello",@"world",@"baby"];

         NSArray*array2 = [array copy];

      这个时候 系统的确是为array2 开辟了一块新的内存空间 但是 array2中的每个元素 只是copy了指向array中相对应元素的指针 这便是所谓的浅复制。

    9、assign和retain

      1.类似与C语言  当你malloc分配了一块内存  并且把它的地址赋给了指针a ,后来希望指针b也共享这一块内存 ,于是你又把a赋值给(assign)了b   。此时a和 b 指向同一块空间 ,当a不再需要这块内存的时候 ,能否直接释放它  答案是否定的 ,因为a并不知道b是否还在使用这块内存 ,如果a释放掉了这块内存  那么b在使用这块内存的时候  程序会crash掉

      2.1当中assign出现的问题如何解决 最简单的方法就是使用引用计数 (reference counting),还是上面的哪个例子  我们给内存设一个引用计数 当内存被分配并赋值给a 的时候  引用计数是1, 当把a赋值给b的时候  引用计数为2  这时如果a不再使用这块内存 ,它只需要把引用计数减1 表明自己不再用于这块内存 。b不再使用这块内存的时候也把引用计数减1  当引用计数为0 的时候 ,代表该内存不再被任何指针指向 系统可以直接把它释放掉。

      总结:上面两点就是assign和retain的区别  assign就是直接赋值 从而可能引起1.中的问题    当数据为int float等原生类型的时候,可以使用assign     retain就如2.中所描述的问题一样  使用了引用计数 retain引起引用计数加1  release 引起引用计数减1 当引用计数为0的时候  dealloc函数被调用  内存被回收。

     http://wenku.baidu.com/link?url=1Tla0N1G4bKsfwNjS6WUXsmDSI7JyzTM8b5TAMpHWpPxdWkqBls158651XysGzsr44Cue-0KcnybqXehLiKE9sZ8DRLuPJ3QQs85f67l9N7

    内容节选自上述地址

        

        

  • 相关阅读:
    时间序列深度学习:seq2seq 模型预测太阳黑子
    时间序列分析工具箱——sweep
    WebApi 找到了与该请求匹配的多个操作
    EF(EntityFramework)与mysql使用,错误终极解决方案
    EF(EntityFramework) 插入或更新数据报错
    EF(EntityFramework)与mysql使用,取数据报错,linq实体映射错误
    EF(EntityFramework)与mysql使用,序列化问题[System.ObjectDisposedException]
    EF(EntityFramework)与mysql使用,乱码问题
    c# AutoMapper 使用方式
    c# json 序列化时遇到错误 error Self referencing loop detected for type
  • 原文地址:https://www.cnblogs.com/ZhuXingzhi/p/3740229.html
Copyright © 2020-2023  润新知