OC语言(五)
三十七.SEL类型-方法的包装
[p performSelector: @selector(Test)];
调用带参数的函数Test:(NSString *)str
假如Test接收一个NSString *参数,注意方法名后面那个冒号。
[p performSelector: @selector(Test:)
withObject:@"test”];
创建SEL数据
SEL s = @selector(xxx:); //冒号表示xxx方法带参数
字符串转SEL:
SEL s = NSSelectorFromString(<NSString>);
每个对象中都有一个SEL变量_cmd,指向当前方法,不能直接打印SEL,要先转成字符串
NSString *s = NSStringFromSEL(_cmd);
三十八.内存管理的概述
三十九.引用计数器(唯一依据)
- (void)setBook:(Book *)book{
_book = [book retain];
}
这样是不严谨的,如果人换了书,无法保证原来的对象不-1,因此做法是先把当前对象-1,然后再把新传入的+1,这样一来,如果
换了书,可以保证原来的-1,没换则不变。这里还用到的一个技巧是空对象发送消息不会报错。
- (void)setBook:(Book *)book{
[_book release];
_book = [book retain];
}
这个依然不严谨,因为有可能_book指向的已经是一个僵尸对象,这时候如果继续release僵尸对象,会出问题。
应该判断_book和传入的book是否是一个对象,如果是一个则不再release,这样既可以避免对僵尸对象操作,又可以避免-1+1这种无意义操作
还有一种可能是_book这时候计数器为1,如果这样,先release则无法再retain。
- (void)setBook:(Book *)book{
if( book!= _book){
[_book release];
_book = [book retain];
}
}
与之对应的,要有release,两种情况,第一种是换了本书,第二种是人死掉了。
- (void)dealloc{
NSLog(@"Person对象被回收");
[_book release];
[super dealloc];
}
set方法规范总结:
1.基本数据类型直接复制 _xxx = xxx;
2.OC对象
if( xxx != _xxx ){ //先判断是不是新对象传入
[_xxx release]; //旧对象release
_xxx = [xxx retain]; //新对象retain
}
dealloc规范:
对当前对象所占有的其他对象进行release。
super的dealloc一定要放到最后吗。
四十一.@property参数
@interface Person : NSObject
{
Car *_car;
int _age;
}
@property int age;
@property (retain) Car* car;
@end
#import <Foundation/Foundation.h>
@class Card;
@interface Person : NSObject
@property (nonatomic, retain) Card *card;
@end
Car.h:
#import <Foundation/Foundation.h>
@class Person;
@interface Card : NSObject
@property (nonatomic, retain) Person *person;
@end
缺点:没有导入类的内容,在.m中如果用到这个类注意引入.h文件。
#import "Person.h"
#import "Card.h"
@implementation Person
- (void)dealloc{
[_card release];
[super dealloc];
}
@end
#import "Card.h"
#import "Person.h"
@implementation Card
- (void)dealloc{
[_person release];
[super dealloc];
}
@end
总结:
@class是用来声明一个类,仅仅告诉编译器这是一个类名。
.h中用@class声明用到的类,.m中用#import(为了提高编译效率)
@class和#import的区别面试中可能考。
循环retain的解决方案:
一端用retain,另一端用assign。
Person *p = [[Person alloc] init];
Card *c = [[Card alloc] init];
p.card = c;
c.person = p;
[c release];
[p release];
这样c和p均不能释放。
一端assign,一段release,用assign的一端注意去掉dealloc的release。
四十四.autorelease方法
Person *p = [[[Person alloc ] init] autorelease];
autorelease会将对象放到自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作。
自动释放池的创建
@autoreleasepool {
Person *p = [[[Person alloc ] init] autorelease];
p.;
}
大括号结束就代表销毁池子。
autorelease使用注意:
1.释放池是可以嵌套的,池子嵌套内层池子入池子。
2.池子是个栈(LIFO),最先入栈的最后释放。
3.池子不能精确控制,因此对于占用内存较大的,和需要精确控制的(例如子弹),应该用release手动释放。
4.返回对象本身,不改变计数器。
5.连续两次调用autorelease,相当于加入了两次对象,会被release两次。
在IOS运行过程中,会创建无数个池子,都是以栈(LIFO)形式存在。
当一个对象调用autorelease方法时,会将对象放到栈顶的释放池。
自动释放的时机:如触摸时。
IOS5.O以前创建NSAutoreleasePool对象pool来创建。
直到[pool release]会销毁中间的对象。
[pool drain]也是一种销毁池子的方式。
用类方法返回autorelease对象。
+ (id)person{
return [[[Person alloc] init] autorelease];
}
NSString创建出的是默认autorelease的。
stringWithFormat方法创建的也不需要自己release。
技巧:只要方法名里面没有alloc,都是autorelease,就不需要release。方法名里有alloc但是没有autorelease就需要。
规范:设计这种autorelease方法是将类名小写然后加上WithXxx。
为了解决继承的问题,注意不要将类名写死,而是使用self。方法内部尽量使用self,这样可以满足子类要求。
+ (id)person{
return [[[self alloc] init] autorelease];
}
+ (id)personWithAge:(int)age{
Person *p = [self person];
p.age = age;
return p;
}
四十五.ARC基本原理
OC语言(五)的更多相关文章
- iOS开发-OC语言 (五)字典
字典 主要知识点: 1.NSDictionary 类 2.NSMutableDictionary 类 3.了解NSMutableDictionary 与 NSDictionary 的继承关系 4.补充 ...
- oc语言学习之基础知识点介绍(五):OC进阶
一.点语法介绍 /* 以前封装后,要给属性赋值,必须调用方法 这样做,有两个缺点: 1.代码量多,调用方法要写的东西多. 2.看起来并不像是给属性赋值,也不像取值. 我们用点语法就可以更好的解决! 点 ...
- oc语言学习之基础知识点介绍(二):类和对象的进一步介绍
一.类.对象在内存中的存储 /* 内存分区: 栈:局部变量 堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造 ...
- OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法
一. 分类-Category 1. 基本用途:Category 分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...
- OC语言(一)
一.概述 1.基本上所有关键词@开头 2.字符串以@开头,如@"Hello" 3.基本数据类型 char int float double BOOL(YES\NO) 4.空为nil ...
- OC语言Block 续
OC语言 Block 转载:http://blog.csdn.net/weidfyr/article/details/48138167 1.Block对象中的变量行为 结论: 在block代码块内部可 ...
- swift调用oc语言文件,第三方库文件或者自己创建的oc文件——简书作者
Swift是怎样调用OC的第三方库的呢?请看下面详情: 情况一: 1.首先打开Xcode,iOS->Application->Single View Application, 选Next. ...
- OC语言前期准备
OC语言前期准备 一.OC简介 Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码. 可以使用OC开发mac osx平台和ios平台的应 ...
- OC语言基础知识
OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...
- OC语言@property @synthesize和id
OC语言@property @synthesize和id 一.@property @synthesize关键字 注意:这两个关键字是编译器特性,让xcode可以自动生成getter和setter的声明 ...
随机推荐
- 自定义支持多行显示的RadioGroup
自定义支持多行显示的RadioGroup 原生的RadioGroup继承自LinearLayout,即只能支持一横排或者一竖排的排列显示RadioButton 现在改写RadioGroup,使它支持多 ...
- Dynamics CRM2016 Web API获取实体元数据Picklist属性的Text&Value
通过组织服务中获取实体picklist字段的text和value可以通过RetrieveAttributeRequest实现,但在使用web api的今天该怎么实现,本文即来一探究竟,本篇基于SDK中 ...
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
Android音频处理--通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能 音频这方面很博大精深,我这里肯定讲不了什么高级的东西,最多也只是一些基础类知识,首先,我们要介绍一下 ...
- PHP Ajax JavaScript Json 实现天气信息获取
使用第三方服务 间接方式 思路 使用到的服务 实现代码 前端完整代码 总结 要在自己的网站上添加一个天气预报功能,是一个很普通的需求,实现起来也不是很难.今天来介绍几个简单的方法. 使用第三方服务 有 ...
- named let 递归和闭包的利器
named let和递归,闭包联系十分密切.而且还是提高性能的重要手段.先来看一个make-list函数的模拟,最原始的写法大概是: (define (imake-list n member) ( n ...
- SpriteKit塔防游戏动态改变防御塔价格标签的颜色
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 本篇blog在DinoDefense塔防游戏基础之上做一处小的 ...
- JavaScript与jQuery获取相邻控件
原始代码如下,需求是onclick中的OpenIframe方法捕捉到input中的value值,由于某些限制无法使用正常的操作dom根据name值来取,所以决定通过相邻空间的方式获取 <div& ...
- 学习TensorFlow,concat连接两个(或多个)通道
深度学习中,我们经常要使用的技术之一,连接连个通道作为下一个网络层的输入,那么在tensorflow怎么来实现呢? 我查看了tensorflow的API,找到了这个函数: tf.concat(conc ...
- RecyclerView下拉刷新上拉加载(三)—对Adapter的封装
RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...