OC self = [super init] , 点语法 , @property

构造方法为啥这么写?

self = [super init];

[super init] 的结果可能有三种:

第一种: [super init] 初始化成功,这个是最最正常的情况。

第二种: [super init] 初始化失败,我们都知道oc的两步创建,alloc开辟内存空间,init初始化对象,但是init还有另外一个作用,在初始化失败的时候,init方法会返回一个nil。回头行文的最上面,如果self为nil,那么if(self)语句的内容,将不被执行,已确保程序健壮安全。

第三种:self = [super init]执行之后,内存指向了不相关的地址。这种情况的出现,一般是一下几种情况:单例、类簇、对象为NSNumber类型、父类在初始化的时候释放了当前对象,然后重新开辟了新的内存地址。

一般情况下都要用以上语句来防止父类改变对象的内存地址导致self指针指向无效内存。

深入构造方法:

在子类自定义构造方法中调用父类自定义构造方法,降低代码的耦合性。

举例:

- (instancetype)initWithName:(NSString *)name age:(int)age no:(int)no
{
self = [super initWithName:name age:age];
if (self) {
_no = no;
}
return self;
}

点语法:

  1. 在OC中点语法不是访问成员变量,而是隐式调用get / set方法 :  

    person.age = 10等效于[person setAge:10];  

    int  age = person.age 等效于 [person age];
  2. 通过在get / set方法中打印数据(或设置断点的方式 ), 可以观察到方法的调用 。
  3. set/get方法里不要调用点语法,会造成死循环

合成存取器:

@property的格式:

@property (修饰列表) 变量类型 变量名;

Xcode4.4之前:

@property使编译器自定生成set/get方法声明。

@synthesize自动生成set/get方法的实现

@synthesize还会自动生成私有成员变量

Xcode4.4以后:不用再写@synthesize,编译器通过@property就能给我们生成set/get方法的声明和实现,默认生成成员变量:_propertyName

用@property生成的成员变量是私有的。

当我们想改变默认的成员变量名时,@synthesize age = newName;

如果子类想访问父类的成员变量,

  1. 通过set/get方法
  2. 显示的声明成员变量
OC提供@property的修饰词有():
  • atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟ARM平台和内部锁机制有关。

  • nonatomic:nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。它的效率比atomic快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。

  • readwrite(默认):readwrite是默认值,表示该属性同时拥有setter和getter。

  • readonly: readonly表示只有getter没有setter。

  • assign :简单赋值,不更改索引计数,假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉.对基础数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等)适用.

  • retain:(MRC)与strong相对应,使用了引用计数,retain+1,release -1;当引用 计数为0时,dealloc会被调用,内存被释放

  • copy:用于非共享内存时,每个指针有自己的内存空间

  • strong:(ARC中默认属性),等于非ARC中的retain,与retain相对应,

  • weak:与assign 相对应,用于IBOutlets,如,UIViewController的子类,即一般的控件。

strong与weak的区别举例(摘自他人博客):

前提:

我们把要用strong或者weak的对象比作一只风筝,风筝想挣脱线的束缚,自由飞翔去,如果此时有一根线,那么这只风筝就挣脱不了

过程分析

strong属性的变量:

当我们把指向一只风筝的变量声明为strong时,此时,你就拥有控制这只风筝的线,假如此时有五个人同时控制这只风筝(即这只风筝对象有三个strong类型的变量指向它),那么只有一种情况,这只风筝才会挣脱掉线的束缚:这三个人都放掉手中的线,(release掉).

weak属性的变量:

当我们把指向一只风筝的变量声明为weak时,此时,就像站在旁边看风筝的观众们一样,当上面的三个人还握着手中的线时,他们只能看到风筝,并不能控制它,他们能做的只能是用手指指向风筝,并大喊,“看,那只风筝飞得真高!”,然而,当上面的三个人把手中的线都放掉时,此时,风筝飞走了,看不见了,不管有再多的观众,他们再也看不到风筝了,这个故事告诉我们一个道理:当strong类型的指针被释放掉之后,所有的指向同一个对象的weak指针都会被清零。

OC self = [super init] , 点语法 , @property的更多相关文章

  1. Swift - Property ''not initialized at super.init call

    Property ''not initialized at super.init call 这个错误应该挺常见的的,为什么在百度上没有找到呢,stack over flow找到了,也不能说是什么解决办 ...

  2. 关于self和super在oc中的疑惑与分析 (self= [super init])

    这个问题貌似很初级,但很容易让人忽略,me too .直到在一次面试时被问到,稀里糊涂的回答了下.实在惭愧, 面试一定都是很注重 基础的,不管高级还是初级. 虽然基础好跟基础不好都可以写代码,网上那么 ...

  3. Objective-C语言的 if ( self = [super init] )

    我们先假设如今自己创建了个类.我们起名叫MyObject,继承于NSObject. 继承知道吧,就是你这个子类(MyObject)假设什么都不写的话,和父类(NSObject)就是一模一样的. OC里 ...

  4. [转] "self = [super init]"的解释与潜藏bug

    Objective-C的推荐init方法写法如下: - (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; } 这里 ...

  5. iOS self = [super init]

    self = [super init] 这个问题一直不太明白,今天研究了一下,在stackoverflow找到了下面的答案: http://stackoverflow.com/questions/29 ...

  6. [super init]方法的调用

    当重新覆盖父类的init方法时,需要调用[super init]方法确认父类中的init是返回一个实例,而不是一个空的实例. 那为什么要调用这个呢? 我得猜测是这样的:因为这是一个初始化方法,需要对对 ...

  7. 刨根问底:对于 self = [super init] 的思考

    对象初始化有两种方式:[class new] 与 [[class alloc] init] 对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的 ...

  8. OC中自定义init方法

    ---恢复内容开始--- 我们知道,在函数中实例化一个对象,大多数会同时进行初始化,如 Person *p =[ [Person alloc]init]; 此时已经进行了初始化,使用init方法,那么 ...

  9. swift中的如果在构造方法中使用KVC, 调用了super.init(), 报错, 基本数据类型属性找不到

    swift要求, 属性必须有初始化值, 如果不对其赋值, 可以加一个?系统会默认给其包装一个可选值(直说就是nil) 如果定义一个基本类型, 建议直接赋值, 不建议使用? 下面说下标题中的问题 有时候 ...

随机推荐

  1. 【转载】使用Lucene.NET实现数据检索功能

    1.索引的管理 //指定索引库文件存放文件位置 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(this.IndexDataDir ...

  2. 使用Tuple来实现多个Model传送至视图

    前面Insus.NET实现过<使用ViewModel来实现多个Model传送至视图>http://www.cnblogs.com/insus/p/5594134.html 和<使用E ...

  3. java实现的排序(插入/希尔/归并)

    java实现三种简单的排序,以下是代码: /*插入排序*/ public static void insertionSort(int[] a) { int j; for(int p = 1; p &l ...

  4. http服务器返回状态代码含义

    100 - 表示已收到请求的一部分,正在继续发送余下部分. 101 - 切换协议. 2xx - 成功.服务器成功地接受了客户端请求: 200 - 确定.客户端请求已成功. 201 - 已创建. 202 ...

  5. MVC之前的那点事儿系列(5):Http Pipeline详细分析(下)

    文章内容 接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件,比如如下代码: public class ...

  6. 【Java每日一题】20161021

    20161020问题解析请点击今日问题下方的"[Java每日一题]20161021"查看 package Oct2016; public class Ques1021 { publ ...

  7. 第 27 章 CSS 传统布局[上]

    学习要点: 1.布局模型 2.表格布局 3.浮动布局 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 早期所使用的传统布局,很多情况下,这些布局方式还是非常有用的. 一.布局模型 在早期没有平 ...

  8. Scalaz(6)- typeclass:Functor-just map

    Functor是范畴学(Category theory)里的概念.不过无须担心,我们在scala FP编程里并不需要先掌握范畴学知识的.在scalaz里,Functor就是一个普通的typeclass ...

  9. python套接字基本使用

    socket socket通常也称作"套接字",用于描述IP地址和端口,应用程序通常通过"套接字"向网络发出请求或者应答网络请求,可以认为是一种计算机网络的数据 ...

  10. Android总结篇系列:Android Intent

    Intent在Android中的重要性不言而喻.本文主要总结下Intent使用过程中需要注意的一些问题. 1.隐式Intent AndroidManifest.xml声明时<intent-fil ...