NSString NSMutableString copy mutableCopy retain weak strong整合
copy retain assign的差别在于对象属性的set方法
- NSString 与 NSMutableString
NSString是不可变字符串对象,这句话的意思,结合代码:
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str = @"Shaw"; NSString *str1 = @"Root"; // NSString *str1的意思是str1指向的@"Root"对象是不可变的,但str1是可以改变指向的。 NSLog(@"str = %@, str1 = %@",str,str1); NSLog(@"str:%p, str1:%p",str,str1); str = [str stringByAppendingString:@"andRoot"]; // 打印可以看到str地址变了,因为原地址下的对象是不可变的。 NSLog(@"str:%p, str1:%p",str,str1); str1 = str; // 使str1指向str对象 NSLog(@"str = %@, str1 = %@",str,str1); NSLog(@"str:%p, str1:%p",str,str1); } ; }// 输出结果 -- :::] str = Shaw, str1 = Root -- :::] str:0x100001050, str1:0x100001070 -- :::] str:0x1001026b0, str1:0x100001070 -- :::] str = ShawandRoot, str1 = ShawandRoot -- :::] str:0x1001026b0, str1:0x1001026b0 Program ended with exit code:
同理,NSMutableString就是可变字符串对象。
stringByAppendingString:方法的定义为:- (NSString *)stringByAppendingString:(NSString *)aString;
NSMutableString *mStr = [NSMutableString stringWithString:@"Shaw"]; NSLog(@"%@ %p",mStr,mStr); [mStr appendString:@"andRoot"]; // 可以看到输出地址为同一个,即对当前对象做了改变。 NSLog(@"%@ %p",mStr,mStr); // 输出结果 -- :::] Shaw 0x100203470 -- :::] ShawandRoot 0x100203470 Program ended with exit code:
如果用NSMutableString对象调用stringByAppendingString:方法会出现警告"Incompatible pointer types assigning NSMutableString to NSString"
- mutableCopy(遵从NSMutableCopying协议的对象可用) 与 copy (遵从NSCopying协议的对象可用)
前者返回的对象是可变的, 后者返回的是不可变的
所以用copy方法返回的字符串是NSString *, mutableCopy方法返回的字符串是NSMutableString *.
有如下的结果:
复制不可变对象时
1. copy是浅复制,即指针复制,两个指针都指向那块空间
2. mutableCopy是深复制,即新开辟一块空间,将对象复制过去
复制可变对象时
mutableCopy与copy都是深复制,但copy返回的对象不可变
下面可以用代码一一验证:
// 复制不可变对象 NSString *str = @"Shaw"; NSString *strCopy = [str copy]; // 相当于 [str retain] NSMutableString *strMCopy = [str mutableCopy]; NSLog(@"%@:%p %@:%p %@:%p",str,str,strCopy,strCopy,strMCopy,strMCopy); strCopy = [str stringByAppendingString:@"andRoot"]; strMCopy = [strMCopy stringByAppendingString:@"andRoot"]; NSLog(@"%@:%p %@:%p %@:%p",str,str,strCopy,strCopy,strMCopy,strMCopy); // 输出结果 -- :::] Shaw:0x100001050 Shaw:0x100001050 Shaw:0x100600380 -- :::] Shaw:0x100001050 ShawandRoot:0x100103870 Shaw:0x100600380
用copy方法复制NSString对象, 出于性能原因, 既然二者本身都不可变,那么不如直接返回源对象,所以二者返回地址一样,所以是浅复制,也就相当于对源对象做retain
因为strCopy是NSString对象,执行第12行代码,是开辟了另一块空间(0x100103870)的,并没有改变之前那块空间(0x100001050)的对象.
// 复制可变对象 NSMutableString *mStr = [NSMutableString stringWithString:@"Shaw"]; NSMutableString *strMCopy = [mStr mutableCopy]; NSString *strCopy = [mStr copy]; // NSLog(@"%@:%p %@:%p %@:%p",mStr,mStr,strMCopy,strMCopy,strCopy,strCopy); NSString *mStrCopy = [mStr copy]; // 打印结果可以看出mStrCopy和strCopy其实是同一个对象,也就是说可变对象的copy只能新开一块空间出来,之后再copy也都是指向这块空间的对象。 NSLog(@"%@:%p %@:%p %@:%p %@:%p",mStr,mStr,strMCopy,strMCopy,strCopy,strCopy,mStrCopy,mStrCopy); strMCopy = [strMCopy stringByAppendingString:@"andRoot"]; // 会放在新地址 strCopy = [strCopy stringByAppendingString:@"andRoot"]; // 会放在新地址 NSLog(@"%@:%p %@:%p %@:%p",mStr,mStr,strMCopy,strMCopy,strCopy,strCopy); // 输出结果 -- :::] Shaw:0x100400290 Shaw:0x1004004d0 Shaw:0x7761685345 Shaw:0x7761685345 -- :::] Shaw:0x100400290 ShawandRoot:0x100400900 ShawandRoot:0x100400550
为什么NSString对象在@property属性声明时写的是copy?
// 假设Person类中有声明如下 // .h @property (nonatomic, copy) NSString *name; // main.m Person *per = [Person alloc] init]; NSMutableString *mStr = [NSMutableString stringWithFormat:@"Root"]; per.name = mStr; NSLog(@"name is %@ now", per.name); [mStr appendString:@"andShaw"]; NSLog(@"name is %@ now ", per.name); // 输出结果会是这样 name is Root now name is Root now
而将copy改为retain
输出结果会是
name is Root now
name is RootandShaw now
set方法的例子
setName:(NSString *)name { if (_name != name) { [_name release]; _name = [name retain]; // copy时此处将retain换成copy } }
总结:
复制方法存在的目的就是为了复制出一个当对它做出改变而不会影响源对象的对象.
当然如果想改变一个NSString对象也不是不可以
比如
NSString *str =@"Shaw"; NSLog("str = %@, addr = %p", str, str); NSString *__strong *p = &str; *p = @"Root"; NSLog("str = %@, addr = %p", str, str); // 输出结果在同一个地址,且已经改变
至于__strong , 是对象ownership的话题了.
- retain weak strong(用rayWenderlich的文章来说)
weak strong是ARC引入的关键词。
strong指针
NSString *firstName = @"Ray";
firstName这个strong指针拥有@"Ray"对象
此时猜想一个textField,当输入Ray
self.textField.text = @"Ray";
此时有两个strong指针指向此对象
textField中的文字变化 变成Rayman
此时就变成下图的样子
只有当firstName被赋予新值,或者含有此局部变量的方法结束,或者因为firstName是一个实例变量且它所属的那个对象已经deallocated,这种所有权才结束。
当@"Ray"不再被任何强指针拥有,它就被释放了。
把firstName和self.textField.text这种指针称为strong指针,因为它们使对象存在于内存中。
默认情况下的实例变量,局部变量都是强指针。
weak指针
__weak NSString *weakName = self.textField.text; // weak指针是需要显式声明的,用__weak关键字
weakName指向对象但并没有拥有它,如果textField内容发生变动,那么@"Rayman"对象不再被任何强指针指向,它会被释放掉。
weak比assign多了一个作用就是当它指向的对象已经被销毁了,它会自己置成nil。
这是非常方便的,因为这防止弱指针继续指向那片已经被释放了的空间,曾经因为这个问题造成了很多bug,你也许有听过"悬摆指针""野指针",但是有了weak指针,这些问题不会出现了。
weak指针多数被用到有父子关系的两个对象上,父对象用strong指向子对象,子对象用weak指向父对象,这样就避免了内存循环,下面是一个例子。
如果是从storyboard中连了线到代码块的,那都是添加到了父视图的子视图树里的,也就是说是有父对象的强指针指向的
// // ViewController.h // test2 // // Created by Shaw on 16/4/6. // Copyright © 2016年 Shaw. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (nonatomic,weak) UIScrollView *scrollView; @end
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(, , , )]; _scrollView = scrollView; [self.view addSubview:self.scrollView]; }
这几句代码可以用下图来描述:
担心scrollView对象有两个强指针指向不好释放?
scrollView变量是个局部变量,出了那个方法,就被释放掉了,之后就只有self一个强指针指向它了。
retain
retain在ARC下是不能显式写的,但是在@property(nonatomic,retain)这样写是没问题的。
retain的属性的setter是先release旧值,再retain新值:
@property (nonatomic,retain) NSString *string; // 当赋给string属性的对象总是NSString *,那么用retain和copy都是一样的
-(void)setString:(NSString *)str{
// if(str == _string){
// return;
// }
[_string release];
_string = [str retain];
}
NSString NSMutableString copy mutableCopy retain weak strong整合的更多相关文章
- IOS开发copy,nonatomic, retain,weak,strong用法
readwrite 是可读可写特性;需要生成getter方法和setter方法时 readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变 ass ...
- nonatomic, retain,weak,strong用法详解
strong weak strong与weak是由ARC新引入的对象变量属性 ARC引入了新的对象的新生命周期限定,即零弱引用.如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自 ...
- Objective-C 中的 assign, copy,retain,strong,weak 详解
在IOS开发中,经常会使用 @property(nonatomic,copy)NSString * name; 语句来快速设置set get 方法,在此依次说明atomic .nonatomi ...
- 【整理】Object-C中的属性(Property)的Setter:assign,copy,retain,weak,strong之间的区别和联系
iOS编程过程中,经常看到一些属性前面有些修饰符,比如copy,retain等. 这些关键字,是Object-C语言中,对于Property的setter. Mac官网: The Objective- ...
- assign, retain, copy, weak, strong
一.assign, retain, copy 的区别(引用计数 RC reference count) 参考:IOS基础:retain,copy,assign及autorelease 1. 假设你用m ...
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
依旧本着尊重原创和劳动者的原则,将地址先贴在前面: http://www.cnblogs.com/nonato/archive/2013/11/28/3447162.html,作者Nonato 以下内 ...
- 【iOS atomic、nonatomic、assign、copy、retain、weak、strong】的定义和区别详解
一.atomic与nonatomic 1.相同点 都是为对象添加get和set方法 2.不同点 atomic为get方法加了一把安全锁(及原子锁),使得方法get线程安全,执行效率慢 nonatomi ...
- iOS中assign,copy,retain之间的区别以及weak和strong的区别
@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Refe ...
- copy,retain,assign,strong,weak的区别
引用地址:http://www.aichengxu.com/view/32930 一.assign,copy,retain 1.copy是内容复制,新建一个相同内容的不同指针,retain为指针复制, ...
随机推荐
- java程序查不出数据来
同样的错误,不可再犯第三次!!! 数据库中是char,里面带空格,但在pl/sql中这样写可以查出来.如下: select ipostid from product t where ipostid= ...
- Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA
版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...
- count(1) count(*)
mysql from t; +---+ | +---+ | | | | +---+ rows in set (0.00 sec) mysql) from t; +----------+ ) | +-- ...
- cocos2d-x 2.1.4学习笔记01:windows平台搭建cocos2d-x开发环境
cocos2d-x的大致开发流程是,首先使用win32版进行代码编写并完成游戏,然后将代码迁移到对应的开发环境上进行交叉编译完成游戏打包,如iphone上是mac+xcode,android是ecli ...
- C#泛型比较大小
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- iOS中的imageIO与image解码
ImageIO对外开放的对象有CGImageSourceRef.CGImageDestinationRef,不对外开放的对象有CGImageMetadataRef.CoreGraphics中经常与im ...
- 有关Color和Drawable你所不知道的那些内容
Android开发中,我们经常会用到Color或Drawable,有时他们是可以混用的,有时却有严格的区别. Drawable 体系结构 Drawable是可绘制物件的一般抽象.与View不同,Dra ...
- MAC地址查询 Linux/Unix操作系统mac地址怎么查
Linux/Unix操作系统熟悉的人都通常是用console命令控制台来进行相应的操作. Linux/Unix操作系统查看网卡mac地址的方法可以通过以下命令获得: 1.ifconfig -a 2. ...
- gulp 实践
文档站YDoc 相关注意事项 sass 编译 目录结构 可以直接使用sass编译 ➜ ydoc git:(v2) ✗ sass ./sass/app.scss ./template/source/ap ...
- Eclipse下使用Hadoop单机模式调试MapReduce程序
在单机模式下Hadoop不会使用HDFS,也不会开启任何Hadoop守护进程,所有程序将在一个JVM上运行并且最多只允许拥有一个reducer 在Eclipse中新创建一个hadoop-test的Ja ...