当前位置: 首页 > news >正文

网站产品分类设计百度做销售网站多少钱

网站产品分类设计,百度做销售网站多少钱,长沙网页,广告设计与制作专业课程深浅拷贝OC对象的拷贝方式分为浅拷贝和深拷贝两种方式浅拷贝本质就是创建一个存放与复制对象相同地址的指针变量,所以也称为指针拷贝深拷贝创建一个与被复制对象的值完全相同的对象,但是他们的地址是不同的,所以也称为内容拷贝对于可变类与非…

深浅拷贝

OC对象的拷贝方式分为浅拷贝和深拷贝两种方式

440295467a24d549bea18f43f0259b18

浅拷贝

本质就是创建一个存放与复制对象相同地址的指针变量,所以也称为指针拷贝

深拷贝

创建一个与被复制对象的值完全相同的对象,但是他们的地址是不同的,所以也称为内容拷贝

对于可变类与非可变类他们的深浅拷贝总结下来就是,不可变类的copy是浅拷贝,mutablecopy是深拷贝。可变类的copy和mutablecopy都是深拷贝

整理

可变对象 -> copy :深拷贝 -> 不可变对象

可变对象 -> mutableCopy : 深拷贝 -> 可变对象

不可变对象 -> copy : 浅拷贝 -> 不可变对象

不可变对象 -> mutableCopy : 深拷贝 -> 可变对象

自定义类的深浅拷贝

  • 自定义类的拷贝必须实现NSCopying与NSMutableCopying协议

  • 自定义对象实现copy与mutableCopy都是深拷贝

NSCopying协议的标准写法

- (id)copyWithZone:(NSZone *)zone {Coffee* coffee = [[[self class] allocWithZone:zone] init];coffee.name = [self.name copy];return coffee;;
}

思考

为什么使用self.class而不是直接写Coffee类?这是为了防止如果后续有子类继承了这个类,但是没有重写copyWithZone:那么父类的实现依然会被调用,使用[self class]可以保证正确生成当前运行时类的实例。而不是Coffee实例对象

归档与解档代码实现

实现解档与归档:之前有了解过,这里再回顾一遍加深印象

关键在与为自定义类实现两个方法,如下

#import "Coffee.h"
​
@implementation Coffee
​
+ (BOOL)supportsSecureCoding {return YES;
}
​
- (void)encodeWithCoder:(NSCoder *)coder {[coder encodeObject:self.name forKey:@"name"];
}
​
- (instancetype)initWithCoder:(NSCoder *)coder {if (self = [super init]) {_name = [coder decodeObjectOfClass:[NSString class] forKey:@"name"];}return self;
}
​
- (id)copyWithZone:(NSZone *)zone {Coffee* coffee = [[[self class] allocWithZone:zone] init];coffee.name = [self.name copy];return coffee;;
}
@end
​//使用
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:coffee requiringSecureCoding:YES error:nil];
​
Coffee* copyCoffee = [NSKeyedUnarchiver unarchivedObjectOfClass:[Coffee class] fromData:data error:nil];

容器类拷贝

单层深拷贝

使用initWithXxx: copyItems:YES方法

int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableString* str = [NSMutableString stringWithString:@"hi"];NSArray* src = @[str];NSArray* dst = [[NSArray alloc] initWithArray:src copyItems:YES];NSLog(@"%p - %p", src[0],dst[0]);NSLog(@"%p - %p", src, dst);}return 0;
}

我们打印结果如下:

发现当容器里面没有容器时,里面一层的元素被深拷贝了,那么如果容器里面的容器的元素呢?我们试一下

int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableString* s = [NSMutableString stringWithString:@"hi"];NSArray* arr = @[s, @[@"hello"]];NSArray* newArr = [[NSArray alloc] initWithArray:arr copyItems:YES];NSLog(@"%p - %p", arr[1][0], newArr[1][0]);}return 0;
}

我们打印结果如下:

显然,里面容器的元素并为被深拷贝,依旧是指针引用

完全深拷贝

当我们想要容器与所有层级的元素都变成彼此独立的新对象时,常用两种方法,一种就是上面的解档归档方法,最方便,代码上面有讲解

属性关键字

通过@property、@synthesized、@dynamic这三个关键字实现属性自动合成存取方法

@property

自动生成属性的setter与getter方法的声明,用于封装对象中的数据,属性本质是ivar + setter + getter

@synthesize

帮我们自动生成setter与getter方法的实现以及合成实例变量

@dynamic

告诉编译器不用自动进行@synthesized,会在运行时提供这些方法的实现,无需产生警告

现在的版本已经不需要在单独写@synthesize了。但是需要注意下面几点

  • 如果重写了setter与getter方法,则编译器就不会自动为这个@property添加@synthesize

  • 如果该属性是readonly,那么只要从写了getter方法,property autosynhesis就不会执行

  • 如果我们在协议中使用@property声明了一个属性,在某个类中遵循这个协议,我们就必须要在类中使用@synthesize来获取这个属性的成员变量,同时获得setter/getter的实现函数

#import <UIKit/UIKit.h>
​
@protocol Demand <NSObject>
- (void)clickButton;
@property(nonatomic, copy)NSString* name;
@end
​
@interface ViewController : UIViewController<Demand>
​
@end
​
​
#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()
@property (nonatomic, strong)UITableView* tableView;
@end
​
@implementation ViewController
@synthesize name = _name;
​
- (void)clickButton {NSLog(@"pop");
}

原子操作

属性是否具有原子性可以理解为线程是否安全

atomic

原子性,加同步锁,是默认的修饰符,使用这个会消耗性能,也不一定保证线层安全,如果需要保证线程安全,需要使用其他锁机制

nonatomic

非原子性,不实用同步锁,声明属性时基本都设置为nonatomic,可以提高访问性能

读写权限

默认为readwrite,属性拥有setter与getter方法

readonly

只读,仅提供getter方法

内存管理

weak

ARC机制下才可以使用,修饰弱引用,不增加对象的引用计数,主要可以用于避免循环引用。weak修饰的对象在释放之后,会自动将指针置为nil,不会产生悬垂指针(指向已经被释放或失效的指针)

assign

既可以修饰基本数据类型,也可以修饰对象类型。setter实现是直接赋值,常用于基本数据类型。修饰对象类型时不增加其引用计数,会产生悬垂指针(其修饰的对象在被释放后,指针依然指向原对象地址,该指针成为悬垂指针,此时如果依然通过该指针访问原对象的话,就可能导致程序崩溃),之所以可以修饰基本数据类型,因为基本数据类型一般分配在栈上,栈的内存会由系统自动处理,不会造野指针。MRC下的delegate往往是assign,此操作是为了防止delegate和self等自身产生循环引用

__unsafe_unretain

与 _weak一样,唯一的区别在于对象即使被销毁,指针也不会被自动置为nil,此时指针指向的是一个无用的地址(悬垂指针),如果使用此地址,程序会抛出异常

下面这段代码可以很好的理解

id __unsafe_unretained temp = [[NSMutableArray alloc] init];
[temp addobject:@"pop"];

为什么会崩溃呢?因为适用这个修饰符的话,不会增加引用计数,并且也不会把指针置为nil,后面使用它的话就是在操作一个已经被释放的对象。

copy

用于修饰OC对象类型,大多是不可变类,在调用setter方法给成员变量赋值时,会先生成一个被复制对象的副本,在将该副本复赋值成员变量

retain
  • MRC下使用,ARC下基本使用strong

  • 修饰强引用,保留旧值,释放旧值,在设置新值,同时引用计数加一

  • setter方法实现如下,先release旧值,retain新值,用于OC对象

- (void)setObj:(NSObject)newObj {if (_obj != newObj) {[_obj release];_obj = [newObj retain];}
}
strong
  • ARC下使用,原理与retain相同,但是在修饰Block时,strong相当于copy,而retain相当于assign(跟block的特性有关,创建是在栈上,使用strong强引用的话,需要将block复制到堆区,延长生命周期)

copy和strong的对比
  • copy:深拷贝,内存地址不同,指针地址也不同,同样是release旧值,copy新值

  • strong:浅拷贝,内存地址不变,指针地址不同,逻辑同retain,(ARC)编译器会在合适的时候自动插入retain/release代码

  • 如果属性声明中指定了copy特性,合成方法会使用类的copy方法。属性并没有mutableCopy特性,即使是可变的实例变量,使用的也是copy特性。会生成一个不可变副本

strong和copy关键字的用法

@property属性用copy修饰不可变对象,用strong修饰可变对象

  • 常用的基本类型对应Foundation数据类型?

在声明一个属性时,尽量使用Foundation框架的数据类型,统一代码的数据类型

  • 定义属性的格式

@property (nonatomic, readwrite, copy) NSString* name;

按照原子操作、读写权限、内存管理排序

  • ARC下@property的默认属性

基本数据类型:atomic、readwrite、assign

OC对象:atomic、readwrite、strong

  • 注意事项

    • 避免使用copy来修饰可变对象

    • 如果一定要用copy的话,就重写setter方法

http://www.dtcms.com/a/428553.html

相关文章:

  • 延安免费做网站公司温州网站推广外包
  • 产业资源+金融赋能!沃飞长空与金石租赁开启深度合作
  • 大余网站app的开发需要多少钱
  • 做网站要到通信管理局备案专业俄文网站建设
  • 苏州电信网站备案泉州市亿民建设发展有限公司网站
  • 新天力:为食品安全而生的食品容器专家
  • 程序员创业注意事项
  • 沃尔沃XC70正式上市,积极布局混插市场的沃尔沃未来何在?
  • 使用lombok的sl4j注解,报错java: 找不到符号 符号: 变量 log
  • 廊坊网站建设搭建wordpress页面管理
  • 26.渗透-.Linux基础命令(十八)-Linux系统状态管理(安全加固-查找空密码账号)
  • 山西网站推婚纱摄影网站的设计与实现
  • 专业直播信号源技术解析:从基础配置到商业解决方案
  • 人物设计网站贵阳网站备案在哪里
  • 学习日报 20250930|多优惠券叠加核销及场景互斥逻辑
  • 在线海报设计网站泊头哪给做网站的好
  • 数据治理3-数元数据管理与治理(资产等)
  • devexpress做网站佛山微信网站建设多少钱
  • 南宁网站搭建人才招聘网站模板html
  • 【UE】判断一个Package是否是重定向器
  • 做网站每年都要费用的吗网页页面设计尺寸
  • 陕西教育建设信息网站小程序模板设计
  • 家纺 网站建设 中企动力中国白客网vip钓鱼网站开发
  • GESP25年9月编程题解析
  • 网站备案负责人幕布照图书馆理论与建设网站
  • Python原生数据结构深度解析:从入门到精通
  • 又拍网站怎么做的网站建设犀牛
  • 有什么网站建设软件有哪些找文网优化服务
  • 视频投票网站怎么做的网站建设分为哪几个步骤
  • 哪些网站做任务可以赚钱的wordpress菜单显示问题