iOS 属性

@property

  • property = ivar(变量) + set方法 + get方法

我们每次在增加一个属性,系统都会在ivar_list 中添加一个成员变量的描述,在method_list中增加settergetter 方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后给出 settergetter方法对应的实现,在setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.

@property (nonatomic, strong)UIView *bgView;

当使用@property声明一个bgView的属性时,在编译阶段,编译器会自动给对象bgView添加一个实例变量_bgView以及它的set方法和get方法

代码验证

#import "ViewController.h"

#include <objc/runtime.h>

@interface ViewController ()

@property (nonatomic, strong)UIView *bgview;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    unsigned int count = 0;
    Ivar *varList = class_copyIvarList([self class], &count);
    for (unsigned int i = 0; i < count; i++) {
        const char *varName = ivar_getName(varList[i]);
        printf("成员变量-------%s\n",varName);
    }
    
    Method *methodList = class_copyMethodList([self class], &count);
    for (unsigned int i = 0; i < count; i++) {
        SEL methodName = method_getName(methodList[i]);
        NSLog(@"方法-------%@",NSStringFromSelector(methodName));
    
    }
}
@end

打印日志

成员变量-------_bgview
2021-03-31 19:19:40.612196+0800 basicLearn[12511:760231] 方法-------bgview
2021-03-31 19:19:40.612294+0800 basicLearn[12511:760231] 方法-------setBgview:
2021-03-31 19:19:40.612378+0800 basicLearn[12511:760231] 方法-------.cxx_destruct
2021-03-31 19:19:40.612465+0800 basicLearn[12511:760231] 方法-------viewDidLoad

  • 如果我们想自定义属性的存取方法,那么需要注意以下几点
    1.同时自定义setget方法,会导致property失效
    image.png

    2.而如果我们重写了set方法,编译器会自动生成get方法,反过来重写了get方法,编译器也会自动生成set方法

@synthesize

  • 当我们需要同时重写属性bgViewsetget方法时,可以用synthesize声明属性
  • 当我们用synthesize声明了属性,但是没有重写setget方法,编译器还是会自动补全存取方法的

代码展示

1.bgView是属性,而_bgView是成员变量
2.@synthesize bgView = _bgView; 这个方法是告诉编译器bgView属性是_bgView实例变量生成settergetter方法的实现

@interface ViewController ()

@property (nonatomic, strong)UIView *bgView;

@end

@implementation ViewController

@synthesize  bgView = _bgView;

- (void)setBgView:(UIView *)bgView {
    _bgView = bgView;
}
- (UIView *)bgView {
    return _bgView;
}

@dynamic

  • @dynamic是告诉编译器 属性 的setter方法 和 getter方法 由用户自己实现
  • 但要注意的是 如果用@dynamic声明一个属性,但没有手动实现settergetter方法,编译时是不会有问题的,但代码运行时调用了属性的set方法或者get方法,程序就会崩溃
  • 还有一个应用:当有一个Father类,里面有一个str的属性,这时创建了一个Son类继承了Father类,在Son类里同时也声明一个str的属性,这时如果我们重写子类Son里的str属性,就会报错,因为我们同时在FatherSon类里声明了str属性,系统默认是会在父类Father里合成str的存取方法,这时我们就需要在子类Son类里用@dynamic修饰str,告诉编译器在子类里不用去合成str属性的存取方法

读写权限 readonly readwrite

  • 如果在声明属性时,没有说明是readonly,那么默认都是readwrite
  • 如果属性被声明为readonly,那么我们获取调用该属性的get方法,调用set方法会报错
@property (nonatomic, copy,readonly)NSString *str;

readonly可以应用在 父类的.h文件将属性设置为readonly,在.m文件又设置为readwrite,那么继承该父类的子类只能获取这个属性而不能修改它的值,只有父类才有权利去修改这个属性的值

原子性 nonatomic atomic

  • atomicnonatomic修饰属性时生成的settergetter方法是不一样的
    atomic修饰属性会在属性的存取方法里加上的同步锁🔒 @synchronized(self),同步锁()里的self可以被其他对象代替,内是根据括号内的内容来判断是否是同一个同步代码块,比如
    当两个并发线程访问同一个对象object中的这个synchronized(self)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  • atomic里的set方法和get方法都加了同步锁🔒,这样可以保证 读写 功能的完成性,但是不能保证对象的线程安全,比如:线程B,C同时调用属性的set方法,线程A去调用get方法,那么get到的值有可能是B设置的,有可能是C设置的,也有可能是B,C之前设置的
  • nonatomic这个的setget方法没有加锁,因此不能保证setget操作的完成性,因此get出的属性可能刚被释放掉,也可能是不完整的,但是由于没有加锁,访问的速度会相对快,性能的消耗也相对少

strong,weak,assign,retain,copy

  • strong

strong 表示强引用,用于修饰NSObject对象,不能修饰基础数据类型,
strong修饰的对象被引用时 引用计数会➕1,当该对象的引用计数为0时,该对象会被释放掉

  • weak

weak 表示弱引用,用于修饰NSObject对象,不能修饰基础数据类型,主要用于避免循环引用,要注意的是:weak修饰的对象才被初始化之后是会释放掉的,对象释放之后所有指向它的指针都会自动置为nil,这样可以防止野指针的问题

//bgView是weak修饰的
//这样初始化之后bgView就会被释放掉
self.bgView = [[UIView alloc]init];
  • assign

assign 可以同时用来修饰基础数据类型(CGFloat等)和对象,当用assign修饰对象时,作用和weak相似,但是对象被释放之后,不会自动将属性置为nil,那么容易出现野指针的问题

  • copy

copy 作用类似与strong,修饰NSObject对象,不能修饰基础数据类型,当copy修饰的属性是可变时(NSMutable),copy后的对象,会变成不可变对象,(比如从NSMutableArray变成NSArray,那么调用增删操作时会引发crash,因为尽量不要用copy修饰可变对象),指针地址跟之前是不一样的,也就是说会重新分配一块新的内存空间

  • retain

一般用于MRC模式下,修饰对象引用计数会加1,后来在ARC模式下基本都使用strong了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容