属性关键字
在了解属性关键字前,先了解了解什么是属性,在刚开始学oc的时候,就学习了成员变量和属性,属性是一种特殊的成员变量,属性和成员变量最大的却别在于属性有自行合成的setter和getter方法。
在写UI控件的时候,我们很容易发现,如果我们在.m文件里新创建一个UI控件,并且对其进行操作,这个控件一般情况下只能在当前函数里进行随意调用。然而如果在属性里创建UI控件,在.m文件里访问时,控件名前面加个下划线或者用self.方法访问,这时这个控件就相当于一个全局变量,在每个函数里都可以调用,因此在写UI时建议把控件都以属性命名,这样简单方便,在调用时还不容易出错。
言归正传,在之前学习深拷贝和浅拷贝的时候就学习过copy和strong两个关键字:
- copy修饰不可变对象、原对象为不可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是浅复制,两个指针指向的是同一个地址。
- copy修饰不可变对象,原对象为可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是深复制,两个对象指向的不同的地址,属性所指的是可变对象的副本,原对象如果被修改的话,不会影响属性的值。
- copy修饰可变对象,如果原对象是不可变对象并赋值给属性,那么进行的是浅复制,指向同一地址。
- copy修饰可变对象,如果原对象是可变对象并赋值给属性,此时进行的是深复制,属性指向的是原对象的不可变副本,即此时属性为不可变对象,这时对属性进行增删改的操作,就会因为找不到方法而报错。
如下图:
刚刚讲到的copy属于setter相关修饰符,属性关键字主要分为四类:
读写性控制
readOnly只读,只会生成getter方法,不会生成setter方法(但外部还是可以用KVC去赋值)
readWrite可读可写,会生成setter方法,也会生成getter方法(默认设置)
这个一般用处不大,除特殊情况外,保持默认readwrite方法即可。
setter相关控制符
setter相关的修饰符表明setter方法应该如何实现
系统默认属性是assign。retain是指针的复制,copy是内容的复制
原子性修饰符:
nonatomic:表示是非线程安全的,使用此属性性能会提高一些。
setter,getter相关修饰符
assign:用于非指针变量。用于基础数据类型(如NSInteger, CGFloat)和C数据类型(int, float, double, char等), 另外还有id类型。
retain:用于指针变量。一般用于字符串(NSString, NSMutableString), 数组(NSMutableArray, NSArray),字典对象,视图对象(UIView),控制器对象(UIViewController)等
通俗来说:
- 使用assign:对基础数据类型(如NSInteger, CGFloat)和C数据类型(int, float, double, char等), 另外还有id类型
- 使用copy:对NSString类型
- 使用retain:对其它NSObject和其子类
//
// ViewController.m
// 属性关键字测试
//
// Created by 翟旭博 on 2022/8/7.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSString* firstString;
@property (nonatomic, copy) NSString* secondString;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSMutableString* textString = [[NSMutableString alloc] initWithString:@"str"];
self.firstString = textString;
self.secondString = textString;
NSLog(@"textSting:%@,firstString:%@,secondStirng:%@",textString,_firstString,_secondString);
NSLog(@"textSting:%p,firstString:%p,secondStirng:%p",textString,_firstString,_secondString);
[textString appendString:@"str"];
NSLog(@"textSting:%@,firstString:%@,secondStirng:%@",textString,_firstString,_secondString);
NSLog(@"textSting:%p,firstString:%p,secondStirng:%p",textString,_firstString,_secondString);
}
@end
输出结果:
用strong修饰的内容改变了,copy修饰的并未改变。
//
// ViewController.m
// 属性关键字测试
//
// Created by 翟旭博 on 2022/8/7.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSArray *firstarray;
@property (nonatomic, copy) NSArray *secondarray;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *testarray = [NSArray arrayWithObjects:@"hello",@"world", nil];
_firstarray = testarray;
_secondarray = testarray;
NSLog(@"%@ %p",testarray, testarray);
NSLog(@"%@ %p",_firstarray, _firstarray);
NSLog(@"%@ %p",_secondarray, _secondarray);
}
@end
输出结果:
我们发现地址是相同的,可得结论:
若使用不可变数组对其进行赋值,那么它们都为浅拷贝,即两个属性的地址和该不可变数组的地址相同,
而若使用可变数组对其进行赋值,使用strong修饰的地址与该可变数组的地址相同为浅拷贝,使用copy修饰的地址与该可变数组的地址不同为深拷贝
原文地址:https://blog.csdn.net/m0_62386635/article/details/126209625
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_36582.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!