OC语言疯狂讲义学习笔记

1、关于nil和Nil及NULL的区别:

nil: A null pointer to an Objective-C object. ( #define nil ((id)0) ) nil 是一个对象值。

Nil: A null pointer to an Objective-C class.

NULL: A null pointer to anything else. ( #define NULL ((void *)0) ) NULL是一个通用指针(泛型指针)。

NSNull: A class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).

[NSNull null]: The singleton instance of NSNull.

[NSNull null]是一个对象,他用在不能使用nil的场合。

2、避免使用僵尸对象的方法

为了防止不小心调用了僵尸对象,可以将对象赋值nil(对象的空值)

?

3、对象的内存泄露

4、@property 参数

内存管理相关参数:

5、@class的使用

作用

可以简单地引用一个类

#### 简单使用

@class Dog; //类的引入

仅仅是告诉编译器: Dog是一个类; 并不会包含Dog这个类的所有内容

具体使用

在.h文件中使用@class引用一个类 在.m文件中使用#import包含这个类的.h文件

通常引用一个类有两种办法:

一种是通过#import方式引入;另一种是通过@class引入; 这两种的方式的区别在于:

1)#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉 编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文 件中真正要用到时,才会真正去查看B类中信息;

2)使用@class方式由于只需要只要被引用类(B类)的名称就可以了,而在实现类由于要用到被 引用类中的实体变量和方法,所以需要使用#import来包含被引用类的头文件;

3)通过上面2点也很容易知道在编译效率上,如果有上百个头文件都#import了同一 个文件,或 者这些文件依次被#improt(A->B, B->C,C->D…),一旦最开始的头文件稍有改动,后面引用到这 个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方 式就不会出现这种问题了;

所以:我们实际开发中尽量在.h头文件中使用@class

4)对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,B类的代码:

作用上的区别

import会包含引用类的所有信息(内容), 包括引用类的变量和方法 @class仅仅是告诉编译器有这么一个类, 具体这个类里有什么信息, 完全不知

效率上的区别

如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头 文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍 , 编译效率非常低 相对来讲,使用@class方式就不会出现这种问题了

6、循环引用

循环retain的场景

比如A对象retain了B对象,B对象retain了A对象 循环retain的弊端 这样会导致A对象和B对象永远无法释放

循环retain的解决方案

当两端互相引用时,应该一端用retain、一端用assign

7、NSString 类的内存管理问题

1)、NSString 等Foundation框架中类的内存管理

先看看以下这几种写法:

NSString *testStr1 = @”a”;

NSString *testStr2 = [NSString stringWithString:@”a”];

NSString *testStr3 = [NSString stringWithFormat:@”b”];

NSString *testStr4 = [[NSString alloc] initWithString:@”c”];

NSString *testStr5 = [[NSString alloc] initWithFormat:@”d”];

NSString *testStr6 = [[NSString alloc] init];

NSLog(@”testStr1 ->%p”,testStr1);

NSLog(@”testStr2 ->%p”,testStr2);

NSLog(@”testStr3 ->%p”,testStr3);

NSLog(@”testStr4 ->%p”,testStr4);

NSLog(@”testStr5 ->%p”,testStr5);

NSLog(@”testStr6 ->%p”,testStr6);

通过对比地址可以看到,从上可以看出,testStr1,testStr2,testStr4都是在一个内存区域,也 就是常量内存区,

1---> NSString *str = [[NSString alloc] initWithString:@"ABC"];
2---> str = @"123";
3---> [str release];
4---> NSLog(@"%@",str);

首先,咱们先对这段代码进行分析。

第一句 声明了一个NSString类型的实例 str, 并将其初始化init后赋值为@”ABC” 第二行,将str的指针指向了一个常量@”123”。 理论上讲在第一行初始化的@”ABC”没有任何任何 指针指向了。 所以造成了内存泄露

然后第三行, 将str的引用计数-1

第四行输出str的值 为123.

首先回答为什么不会崩溃, 因为第三行的release 实际上是release了一个常量@”123” 而作为 常量,其默认的引用计数值是很大的(100k+)

NSLog(@”retainCount = %tu”,[@”123” retainCount]);

最终的输出值会是一个很大很大的数。 所以单单一个release是不会将其释放掉的。

然后再回答这样会不会造成内存泄露。

其实…………理论上讲 会!

但是实际上,Objective-C对NSString类型有特殊照顾。所有的NSString的引用计数器默认初始值 都会非常非常大。

2)、危险的用法

while ([a retainCount] > 0) {
         [a release];
} 

如果运行结果正确,那么这是多么幸运的一个人啊!

8、自动释放池及autorelease介绍

自动释放池

(1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。 (2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中

自动释放池的创建方式

(1)iOS 5.0以前的创建方式

NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
 `````````````````
[pool release];//[pool drain];用于mac

(2)iOS5.0以后

@autoreleasepool
{//开始代表创建自动释放池
      ·······
}//结束代表销毁自动释放池

autorelease

是一种支持引用计数的内存管理方式

它可以暂时的保存某个对象(object),然后在内存池自己的排干(drain)的时候对其中的每个 对象发送release消息 注意,这里只是发送release消息,如果当时的引用计数(reference-counted)依然不为0,则该 对象依然不会被释放。可以用该方法来保存某个对象,也要注意保存之后要释放该对象。

为什么会有autorelease?

(1)不需要再关心对象释放的时间

(2)不需要再关心什么时候调用release

autorelease何时释放?

对于autorelease pool本身,会在如下两个条件发生时候被释放

1)手动释放Autorelease pool

2)Runloop结束后自动释放

对于autorelease pool内部的对象

在引用计数的retain == 0的时候释放。release和autorelease pool 的 drain都会触发retain– 事件。

9、Block

一、静态变量和全局变量 在加和不加 __block都会直接引用变量地址。也就意味着可以修

改变量的值。在没有加__block 参数的情况下。

? 全局block和栈block区别为是否引用了外部变量,堆block则是对栈block copy得来。对全局block

copy 不会有任何作用,返回的依然是全局block。

二, 常量变量(NSString *a = @”hello”;a 为常量变量,@“hello”为常量。)—–不 加__block类型 block 会引用常量的地址(浅拷贝)。加__block类型 block会去引用常量变 量(如:a变量,a = @”abc”.可以任意修改a 指向的内容。)的地址。

时间: 2024-08-27 05:05:40

OC语言疯狂讲义学习笔记的相关文章

李刚OC语言疯狂讲义笔记

设计一个”学生“类1> 属性* 姓名* 生日用结构体作为类的实例变量(生日) #import <Foundation/Foundation.h> //定义生日的结构体 typedef struct{ int year; int month; int day; }MyDate; @interface Person : NSObject { @public NSString *_name;//定义姓名 MyDate _birthday;//定义生日 } @end @implementatio

疯狂Android讲义 - 学习笔记(五)

第五章 Android使用统一的Intent对象来封装“启动意图”,不管是启动Activity.Service组件.或者BroadcastReceiver等,提供了一致的编程模型.Intent设计有点类似于Struts2框架中的逻辑视图设计. Intent还是应用程序组件之间通信的重要媒介:数据封装成Bundle对象,Intent携带Bundle对象. 5.1 Intent对象详解 5.2 Intent的属性及intent-filter配置 5.2.1 Component属性 5.2.2 Act

疯狂Android讲义 - 学习笔记(四)

Android应用通常有多个Activity,多个Activity组成Activity栈,当前活动的Activity位于栈顶.Activity相当于Java Web开发的Servlet.当Activity处于Android应用运行时,同样受系统控制.有生命周期. 4.1 建立.配置和使用Activity 4.1.1 Activity 建立自己的Activity需要集成Activity基类,在不同的应用场景,有时也能集成Activity的子类. Activity间接或直接继承了Context.Co

疯狂Android讲义 - 学习笔记(二)

Android应用的用户界面编程 Android推荐使用XML布局文件来定义用户界面 ViewGroup是一个抽象类,通常使用它的子类作为容器,ViewGroup控制其子组件的分布依赖于两个内部类: ViewGroup.LayoutParams 和 ViewGroup.MarginLayoutParams 疯狂Android讲义 - 学习笔记(二),布布扣,bubuko.com

疯狂Android讲义 - 学习笔记(六)

第7章 7.1 使用简单图片 7.1.1 使用Drawable对象 7.1.2 Bitmap和BitmapFactory 7.2 绘图 7.2.1 Android绘图基础:Canvas.Paint等 Android的绘图应该继承View组件,并重写onDraw(Canvas canvas) 方法即可,Canvas代表了“依附”于指定View的画布.表7.1 Canvas的绘制方法 Paint代表了Canvas上的画笔,Paint类主要用于设置绘制风格,包括画笔颜色.画笔粗细.填充风格等. 7.2

疯狂Android讲义 - 学习笔记(七)

第8章 Android数据存储与IO  Java IO的数据存储可以移植到Android应用开发上来,Android系统还提供了一些专门的IO API. Android系统内置了SQLite数据库,SQLite是轻量级的,没有后台进程,整个数据库对应一个文件,这样可以非常方便的在不同设备之间移植.Android为访问SQLite提供了大量便捷的API. 8.1 使用SharedPreferences 适用于保存简单格式的数据. 8.1.1 SharedPreferences 与 Editor S

疯狂Android讲义 - 学习笔记(八)

第10章 Service与BroadcastReceiver 10.1 Service简介 Service组件也是可执行的程序,有自己的生命周期,创建.配置Service与创建.配置Activity的过程基本相似.Service一直在后台运行,没有用户界面. 10.1.1 创建.配置Service 需要2个步骤:1 定义基础Service的子类,2 在AndroidManifest.xml文件中配置Service. Service与Activity都是从Context派生出来的,因此都可以调用C

《R语言实战》学习笔记seventh

由于在准备软考中级数据库系统工程师外加巩固SQL Server 2012,所以拖了好久一直没继续学R 下去 所以今天重开R 的战事 这次是关于基本统计分析的内容,即关于用于生成基本的描述性统计量和推断统计量的R 函数 首先,将着眼于定量变量的位置和尺度的衡量方式 然后将是生成类别型变量的频数表和列联表的方法(以及连带的卡方检验) 接下来将考察连续型和有序型变量相关系数的多种形式 最后转而通过参数检验(t检验)和非参数检验(Mann-Whitney U检验.Kruskal-Wallis检验)方法研

《R语言实战》学习笔记fourth

又拖了好久继续写R 语言的学习笔记了啊 这次到了基本数据管理了,众所周知数据准备是数据分析的最重要的前提 书本是从一个例子开始本章的内容的,例子是一个类似调查问卷的 然后把回答标为从1到5,再进行分析(这让我想到了自学SPSS 的时候啊) > manager <- c(1, 2, 3, 4, 5) > date <- c("10/24/08", "10/28/08", "10/1/08", "10/12/08&q