美文网首页iOS专题
iOS property修饰关键字

iOS property修饰关键字

作者: 小秀秀耶 | 来源:发表于2018-11-28 16:58 被阅读0次

    内存相关

    ARC : strong、copy 、weak、assign、unsafe_unretained(xcode 4.3、ios5以上版本)
    MRC : retain、weak、copy

    strong:只要某一对象被一个strong指针指向,该对象就不会被销毁。如果对象没有被任何strong指针指向,那么就会被销毁,此时所有剩余的weak型指针都将被清除。在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上跟MRC下得retain是比较相似的

    copy:建立一个索引计数为1 的对象,然后释放旧对象

    copy的用途:

    1. 修饰 NSString、NSArray、NSDictionary

    用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份

    2.修饰 block

    block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。

    思考这个写法会出什么问题: @property (copy) NSMutableArray *array

    1. 添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃.因为 copy 就是复制一个不可变 NSArray 的对象;
    2. 使用了 atomic 属性会严重影响性能 ;

    weak:指针的对象释放后,置为nil

    weak用途:

    1. 在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性
    2. 自身已经对它进行一次强引用,没有必要再强引用一次。如IBOutlet连出来的视图属性被设置成weak,因为ViewController强引用ViewView强引用视图属性,所以没有必要再强引用一次。

    assign: 简单赋值,不改变引用计数,适用于Foundation基础数据类型、C数据类型、id类型

    unsafe_unretained:指针的对象释放后,继续指向对象存在的那个内存,这会导致因为访问那个已释放对象引起的崩溃

    strongweakunsafe_unretained往往都是用来声明属性的,如果想声明临时变量就得用__strong__weak__unsafe_unretained__autoreleasing

    __autoreleasing:可以使对像延迟释放

    __autoreleasing参考地址

    weakassign的区别:

    1. weak 可以修饰对象类型,assign修改基本数据类型
    2. assign 可以用非 OC 对象,而 weak 必须用于 OC 对象

    retain:在MRC环境下,你需要自己retain一个想要保持的对象,用一个指针指向这个对象,只要指针没有被重置为空,对象就会一直在堆上,当指针指向新值的时候,原来的对象就会被release一次

    copyretain的区别

    copy其实是建立了一个相同的对象,而retain不是;

    copy是内容拷贝,retain是指针拷贝;
    copy对于像NSString类型的,的确是内容的拷贝 。如果拷贝的是NSArray这时只是copy了指向array中相对应元素的指针,这便是所谓的浅拷贝。

    __block__weak的区别

    __block不管是ARC还是MRC模式下都可以使用,修饰对象、基本数据类型;
    __weak只能在ARC模式下使用,修饰对象;
    __block对象可以在block中被重新赋值,__weak不可以。

    为什么有__weak还要用__unsafe_unretained呢?

    1. __weak只支持iOS 5.0OS X Mountain Lion作为部署版本(当然对于现在,这个原因已经可以无视了)
    2. __weak对性能会有一定的消耗,使用__weak,需要检查对象是否被释放,在追踪是否被释放的时候当然需要追踪一些信息,那么此时__unsafe_unretained__weak快,而且一个对象有大量的__weak引用对象的时候,当对象被废弃,那么此时就要遍历weak表,把表里所有的指针置空,消耗cpu资源。

    那么什么时候使用__unsafe_unretained呢?

    当你明确对象的生命周期的时候,可以使用__unsafe_unretained替代__weak,可以稍微提高一些性能,虽然这点性能微乎其微。
    举个例子,当A拥有B对象,A消亡B也消亡,这样当B存在,A也一定会存在的时候,此时B要调用A的接口,就可以通过__unsafe_unretained 保持对A的引用关系。

    参考地址1

    参考地址2

    原子性

    atomic:(默认),线程有关,通常用于单线程,速度较慢
    nonatomic: 线程无关,通常用于多线程,速度较快

    atomic : 速度慢, 多线程调用getter、sette方法是线程安全,并不能保证整个对象是线程安全的
    nonatomic : 速度快,多线程不安全

    atomic、nonatomic参考博客地址

    读写相关

    readonly
    readwrite

    readonly : 只读属性,只生成getter方法,也就是说只能访问变量,不能修改
    readwrite : (默认),可读可写,生成setter和getter方法

    方法名

    getter=<name>
    setter=<name>
    @property (nonatomic, getter=isOn) BOOL on;

    能否为空

    nullable
    nonnull
    null_resettable
    null_unspecified

    nonnull、nullable参考博客地址

    nullablenonnullnull_unspecified 修饰属性

    @property(nonatomic,copy,nullable)NSString *string;
    @property(nonatomic,copy)NSString* __nullable string;
    @property(nonatomic,copy)NSString* _Nullable string;
    
    

    nullablenonnullnull_unspecified 修饰方法

    - (void)methodWithString:(nullable NSString*)string;
    - (void)methodWithString:(NSString* _Nullable)string;
    - (void)methodWithString:(NSString* __nullable)string;
    

    总结:

    1. 对于属性、方法返回值、方法参数的修饰,使用: nonnullnullable
    2. 对于 C 函数的参数、Block 的参数、Block 返回值的修饰,使用: _Nonnull_Nullable建议弃用__nonnull__nullable

    Nonnull Audited Regions

    NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END在这两个宏之间的代码,所有简单指针对象都被假定为 nonnull ,因此我们只需要去指定那些 nullable 指针对象即可,Xcode10 、iOS12之后默认添加Nonnull Audited Regions区域

    不过,为了安全起见,苹果还制定了以下几条规则

    1. 通过 typedef 定义的类型的 nullability 特性通常依赖于上下文,即使是在 Nonnull Audited Regions 中,也不能假定它为 nonnull
    2. 对于复杂的指针类型(如 id * )必须显式去指定是 nonnull 还是 nullable。例如,指定一个指向 nullable 对象的 nonnull 指针,可以使用 __nullable id * __nonnull
    3. 我们经常使用的 NSError **通常是被假定为一个指向 nullable NSError 对象的 nullable指针。

    null_resettable : 不为空,只有一种修饰方法

    @property(nonatomic,strong,null_resettable) NSNumber * number;
    

    null_resettable修饰后,必须确保值不能为nil,可以重写settergetter函数,确保值不为nil

    null_unspecified:不确定是否为空

    相关问题

    1.ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?
    1. 对应基本数据类型默认关键字是atomic、readwrite、assign
    2. 对于普通的 Objective-C 对象atomic、readwrite、strong
    2. @property 的本质是什么?

    @property = ivar + getter + setter;
    “属性” (property)有两大概念:ivar(实例变量)、存取方法(access method = getter + setter)。

    3. ivar、getter、setter 是如何生成并添加到这个类中的?

    “自动合成”( autosynthesis)
    完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。需要强调的是,这个过程由编译 器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
    也可以在类的实现代码里通过 @synthesize 语法来指定实例变量的名字.

    4. @protocol 和 category 中如何使用 @property?

    在 protocol 中使用 property 只会生成 setter 和 getter 方法声明,我们使用属性的目的,是希望遵守我协议的对象能实现该属性
    category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给 category 增加属性的实现,需要借助于运行时的两个函数:
    objc_setAssociatedObject
    objc_getAssociatedObject

    5.copymutableCopy

    非集合类对象

    [immutableObject copy] // 浅复制
    [immutableObject mutableCopy] //深复制
    [mutableObject copy] //深复制
    [mutableObject mutableCopy] //深复制

    集合类对象

    [immutableObject copy] // 浅复制
    [immutableObject mutableCopy] //单层深复制
    [mutableObject copy] //单层深复制
    [mutableObject mutableCopy] //单层深复制

    6.@synthesize和@dynamic分别有什么作用?
    1. @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
    1. @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。当我们同时重写了setter and getter方式时,需要在.m的文件中使用@synthesize string1 = _string1;
    1. @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。@dynamic string2;

    招聘一个靠谱的iOS面试题参考答案

    相关文章

      网友评论

        本文标题:iOS property修饰关键字

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