iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期
1. 属性
在开发过程中经常要用到定义属性,@property和@synthesize是经常用到的属性, property在.h文件中作声明,@synthesize在.m文件中用于实现
// Student.h
// property
//
// Created by Rio.King on 13-8-25.
// Copyright (c) 2013年 Rio.King. All rights reserved.
// #import <Foundation/Foundation.h> @interface Student : NSObject
{
int age;
int no;
} //当编译器遇到@property时,会自动展开成getter和setter的声明
@property int age;
@property int no; @end Student.m //
// Student.m
// property
//
// Created by Rio.King on 13-8-25.
// Copyright (c) 2013年 Rio.King. All rights reserved.
// #import "Student.h" @implementation Student //@synthesize 会自动生成getter和setter的实现
//@synthesize 默认会去访问age,no,height同名的变量,,
//如果找不到同名的变量,会在内部自动生成一个私有同名变量age,no,height,,
//因此Student.h 中的这几个变量也可以省略不写。
@synthesize age,no; @end
说明:在xcode4.5以后 可以省略@synthesize ,编译器会自动帮你加上getter 和 setter 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量.
而我在实际开发使用上的经验是 尽量使用”点语法”,可读性更强.涉及setter getter 初始化时候我才会使用_age.
例如: #pragma mark - getter and setter
//当有实例方法中调用 “self.titleLab”就会自动调用以下 setter getter 方法 (UILabel *)titleLab
{
if(!_titleLab){
UILabel * titleLab = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.view.width, HF_BUTTON_HOME_TEST_HEIGHT)];
titleLab.textAlignment = NSTextAlignmentCenter ;
titleLab.text = @"选择生日";
titleLab.font = HF_TITLE_BOLD_FONT ;
[self.view addSubview:titleLab];
_titleLab = titleLab;
}
return _titleLab;
}
2, 认识几个关键字
(1)atomic:原子操作(线程安全) (原子性 是指事物的一个完整操作,操作成功就提交,反之就回滚.原子操作 指的是具有原子性的操作) OC属性设置里面默认是atomic 原子属性,意思是 setter/getter函数就是一个原子操作,如果多线程操作 setter 那么 相当于 在函数头尾加了锁 防止资源竞争造成的死锁.(不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter)
(2)nonatomic:非原子操作(线程不安全) 一般不需要多线程支持的时候 就用 nonatomic.这样并发访问的效率就会比较高.如果 一个属性要在多线程中使用,那么 就该用原子属性的atomic. 但是 在开发iOS程序时应该使用nonatomic属性,因为atomic属性会严重影响性能, 我们一般在使用nonatomic过程中加锁之类的方法做到数据同步.
通常说nonatomic 是提高在非多线程应用中的读写效率 如果问 这俩谁是线程安全的,原子性安全 所以是atomic更安全 @property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;
区别 使用@synthesize,编译器会确实的产生getter和setter方法,而@dynamic仅仅是告诉编译器这两个方法在运行期会有的,无需产生警告。 (3)synthesize 会自动生成getter和setter的实现 如果不实现setter和getter方法,编译器将会自动在生产setter和getter方法
(4) dynamic 就是要来告诉编译器,代码中用@dynamic修饰的属性,其getter和setter方法会在程序运行的时候或者用其他方式动态绑定,以便让编译器通过编译。其主要的作用就是用在NSManageObject对象的属性声明上,由于此类对象的属性一般是从Core Data的属性中生成的,Core Data框架会在程序运行的时候为此类属性生成getter和Setter方法。
假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。这个 时候 自己要写实例方法 进行getter 读取 或者 setter 进行赋值(注意防止方法自己调用自己 造成死循环) 正确使用举例: #pragma mark - getter and setter - (UILabel *)noteLabel
{
if (!_noteLabel) {//_noteLabel在这里是私有创建, 在@dynamic 里不会自己生成
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 64.0 + 22.0, SCREEN_WIDTH - 100, 40.0)];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont boldSystemFontOfSize:16.0]];
[label setTextColor:[UIColor grayColor]];
[label setText:self.noteText];
[label setNumberOfLines:0];
[label setLineBreakMode:NSLineBreakByWordWrapping]; _noteLabel = label;
}
return _noteLabel;
} (4)assign : 简单赋值操作,不更改索引计数
对基本数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等) 适用简单数据类型
(5)strong :我习惯叫它”强引用(apple说是strong reference)”(书上管它叫 拥有关系(owning relationship)) 当前对象被其他对象引用时,会执行retain操作,引用计数器+1。当retainCount=0时,该对象才会被销毁。因为我们要进行对象的内存管理,所以这是默认的引用方式。(默认是强引用)
一个对象只有在它的所有强引用都被释放后才能被回收.
(6)weak :”弱引用”(非拥有关系 nonowning relationship) 当它的生存周期到了时就会被销毁,弱引用在可能会出现循环引用的情况下是必不可少的. strong VS weak
强引用持有对象 弱引用 不持有 当弱引用指向一个强引用所持有的对象时,当强引用赋值为nil 弱引用自动被赋值nil
如果弱引用被赋值为nil 强引用依旧持有原来的对象 strong,weak, unsafe_unretained往往都是用来声明属性的,如果想声明临时变量就得用__strong, __weak, __unsafe_unretained, __autoreleasing, 其用法与上面介绍的类似。 (7)retain :手动释放内存时候使用,相当于ARC中的strong (8)copy :(浅拷贝,指针拷贝)a 和 b 指向同一个对象 共用同一块内存
(9)mutable:(深拷贝,内容拷贝) 做”影子数据”时候使用 是完全新的一个对象 举例:
NSString *string = @"origion";
NSString *stringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy];
[stringMCopy appendString:@"!!"];
//内存
NSLog(@"\n string:%p \n stringCopy:%p \nstringMCopy:%p \n",string,stringCopy,stringMCopy);
//对象
NSLog(@"\n string:%@\nstringCopy:%@\nstringMCopy:%@\n”,string,stringCopy,stringMCopy); 2016-02-16 17:35:04.284 dailylife[1665:183019]
string:0x10d58a4d0
stringCopy:0x10d58a4d0 //copy -> 和string 共用同一块内存地址 (同一个指针)
stringMCopy:0x7f92e47375d0 //multableCopy 新的一块内存指针
2016-02-16 17:35:21.479 dailylife[1665:183019]
string:origion
stringCopy:origion // copy -> 同一个对象
stringMCopy:origion!! //multableCopy 一个新对象
举例2
NSMutableString *string = [NSMutableString stringWithString: @"origion"];
NSString *stringCopy = [string copy];
NSMutableString *mStringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy]; //[mStringCopy appendString:@“mm"];//error 可变字符串应该使用”可变拷贝”multableCopy 才可使用 这类方法
[string appendString:@" origion!"];
[stringMCopy appendString:@"!!"]; //内存
NSLog(@"\n string:%p \n stringCopy:%p \n mStringCopy :%p\nstringMCopy:%p \n",string,stringCopy,mStringCopy,stringMCopy);
//对象
NSLog(@"\n string:%@\nstringCopy:%@\nmStringCopy:%@\nstringMCopy:%@\n”,string,stringCopy,mStringCopy,stringMCopy); 2016-02-16 17:54:46.019 dailylife[2039:201349]
string:0x7ff993f71800
stringCopy:0x7ff993f71860
mStringCopy :0x7ff993f71880
stringMCopy:0x7ff993f718a0 //四个不同对象不同指针 2016-02-16 17:54:48.107 dailylife[2039:201349]
string:origion origion!
stringCopy:origion
mStringCopy:origion
stringMCopy:origion!! //四个不同对象不同指针
iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期的更多相关文章
- iOS 52个技巧学习心得笔记 第一章 熟悉OC
1 .简单了解OC2 .在类的头文件中尽量少引入其他头文件3 .多用字面量语法 少用与之等价的方法 4 .多用类型常量 少用 #define 预处理指令5 .用枚举表示状态,选项,状态码 .简单了解O ...
- 《疯狂Java:突破程序员基本功的16课》读书笔记-第二章 对象与内存控制
Java内存管理分为两个方面:内存分配和内存回收.这里的内存分配特指创建Java对象时JVM为该对象在堆内存中所分配的内存空间.内存回收指的是当该Java对象失去引用,变成垃圾时,JVM的垃圾回收机制 ...
- 《DOM Scripting》学习笔记-——第二章 js语法
<Dom Scripting>学习笔记 第二章 Javascript语法 本章内容: 1.语句. 2.变量和数组. 3.运算符. 4.条件语句和循环语句. 5.函数和对象. 语句(stat ...
- The Road to learn React书籍学习笔记(第二章)
The Road to learn React书籍学习笔记(第二章) 组件的内部状态 组件的内部状态也称为局部状态,允许保存.修改和删除在组件内部的属性,使用ES6类组件可以在构造函数中初始化组件的状 ...
- [HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的“HT”
[HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的"HT" 敲黑板!!! 创建HTML超链接 <a>链接文本(此处会有下划线,可以单击 ...
- python学习心得第五章
python学习心得第五章 1.冒泡排序: 冒泡是一种基础的算法,通过这算法可以将一堆值进行有效的排列,可以是从大到小,可以从小到大,条件是任意给出的. 冒泡的原理: 将需要比较的数(n个)有序的两个 ...
- python学习心得第四章
python 学习心得第四章 1.lambda表达式 1:什么是lambda表达式 为了简化简单函数的代码,选择使用lambda表达式 上面两个函数的表达式虽然不一样,但是本质是一样的,并且lamb ...
- Android群英传笔记——第二章:Android开发工具新接触
Android群英传笔记--第二章:Android开发工具新接触 其实这一章并没什么可讲的,前面的安装Android studio的我们可以直接跳过,如果有兴趣的,可以去看看Google主推-Andr ...
- 深入理解 C 指针阅读笔记 -- 第二章
Chapter2.h #ifndef __CHAPTER_2_ #define __CHAPTER_2_ /*<深入理解C指针>学习笔记 -- 第二章*/ /* 内存泄露的两种形式 1.忘 ...
随机推荐
- Yarn源码分析之MapReduce作业中任务Task调度整体流程(一)
v2版本的MapReduce作业中,作业JOB_SETUP_COMPLETED事件的发生,即作业SETUP阶段完成事件,会触发作业由SETUP状态转换到RUNNING状态,而作业状态转换中涉及作业信息 ...
- 华为终端开放实验室Android P Beta 4测试能力上线
7月26日,Android P Beta 4发布(即Android P DP5),此版本为开发者最后一个预览版本,也预示着Android P正式版即将与大家见面. 为保证开发者在正式版本来临前做好充分 ...
- 介绍两款Linux文件恢复工具,ext3grep与extundelete https://www.cnblogs.com/lazyfang/p/7699994.html
介绍两款Linux文件恢复工具,ext3grep与extundelete,可能在关键时刻会有所帮助.ext3grep仅对ext3文件系统有效,extundelete对ext3与ext4文件系统都有效 ...
- windows下mysql表名不自动转换小写配置
mysql5.6版本配置文件有两个 1.默认的配置在program files/MySQL/MySQL Server 5.6/my-default.ini 2.一个在programData/MySQL ...
- Fibonacci数列的幂和 zoj 3774
题目大意: 求斐波那契数列前n项的k次幂和 Mod 1000000009. n<=1e18, k<=1e5 这题的k比较大,所以不能用矩阵乘法来递推.学到了新姿势... http ...
- NetCore 中 EFcore的DbFirst和CodeFirst混合 使用注意
NetCore 最近很火热.笔者想把自己以前的旧项目迁移到NetCore平台. 先用EFcore的DBFirst根据数据库创建实体类,然后加入数据库版本控制功能也就是EFcore的CodeFirst部 ...
- Laravel中创建控制器
<?php /** * Created by PhpStorm. * User: chuang * Date: 17-1-14 * Time: 下午4:29 */ namespace App\H ...
- 如何获取继承中泛型T的类型
@SuppressWarnings("unchecked") public void testT() { clazz = (Class<T>)( (Parameteri ...
- 创建新的C++工程来调用Caffe对图片进行识别
前段时间一直在跑Caffe训练数据.之前用训练好的caffemodel对图片进行分类都是用的命令行指令,于是就想着自己新建一个工程来调用caffe,结合classification的代码来对图片进行分 ...
- std::condition_variable(3)复习
#include <iostream> // std::cout #include <thread> // std::thread #include <mutex> ...