property
retain:自动生成getter/setter方法,并且生成的是内存管理代码(引用计数器+1)。
assign:不会自动在setter/getter方法中生成内存管理代码,只生成普通的getter与setter方法
Setter:
-(void)setUseName:(NSString *)useName
{
if (_useName != useName) {
[_useName release]; //让原有的实例变量release一次
_useName = nil; //清空实例变量指针
_useName = [useName retain]; //将新的对象retain后赋值给实例变量。因为在对象释放的时候,会对里面的实例对象进行一次release操作
}
}
Getter:
-(NSString *)useName
{
return _useName;
}
block的存储地址
1.block默认存储在栈中,如果对block进行一次 copy操作,block就会转移到堆中存储。
2.如果block在栈中存储时,block访问了外部的对象,那么不会对对象进行retain操作。
3.如果block在堆中存储,block访问了外部对象,那么会对外部对象进行一次retain操作。
4.只要给外部的对象前面加上__block,不管block是堆中还是栈中,都不会对对象进行retain操作
nil、Nil、NULL
nil 针对对象,指向OC中对象的空指针。
Nil 针对类,指向OC中类的空指针。
NULL 针对其他数据类型,指向其他类型的空指针。如基本数据类型为空。
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //单层深复制
[mutableObject copy] //单层深复制
[mutableObject mutableCopy] //单层深复制
295346-bd95431918be69b1.png
atomic对象setter和getter方法的实现:
- (void)setCurrentImage:(UIImage *)currentImage
{
@synchronized(self) {
if (_currentImage != currentImage) {
[_currentImage release];
_currentImage = nil;
_currentImage = [currentImage retain];
}
}
}
- (UIImage *)currentImage
{
@synchronized(self) {
return _currentImage;
}
}
为什么修饰符使用copy
用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
runtime
引自:http://weibo.com/luohanchenyilong/、https://github.com/ChenYilong
// runtime.h(类在runtime中的定义)
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY; //isa指针指向Meta Class,因为Objc的类的本身也是一个Object,为了处理这个关系,runtime就创造了Meta Class,当给类发送[NSObject alloc]这样消息时,实际上是把这个消息发给了Class Object
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
***令调用new的代码在编译器直接报错
+(instancetype) new attribute((unavailable("OneTimeClass类只能初始化一次")));
网友评论