OC方面的基础笔记摘录

OC方面的基础笔记摘录:

1.类的基本用法

#import <Foundation/Foundation.h>
// 大体上就是include, 用于包含头文件, 但是即使头文件中, 没有ifndef defined endif, 仍然能够踢除重复包含的头文件
// [email protected] section----
// OC中声明和实现是分离的, 两个都必须有.
@interface Fraction : NSObject {    // @interface 类名: 父类名字
// 在这里声明成员变量, 在OC中称为字段, 描述类的对象的属性
// 只有成员变量需要在外部提供接口, 或者是需要被继承的时候, 才需要在.h文件中定义成员变量, 其他情况下只需要在.m文件中, 声明全局变量即可
   int _numerator;    // 在类内一律使用成员变量, 在类外使用属性
   int _denominator;
}
@property (nonatomic, assign) int numerator, denominator;
-(void) setNumerator: (int) n;        // 声明方法
-(void) setNumerator: (int) n andDenominator: (int) d;
-(Fraction *) init;    // 或者使用-(id) init; OC中只要是以init开头的都是构造函数, 可以带参数
@end

// [email protected] section----方法的实现---实例方法(以-号开头)----类方法(以+号开头)
@implementation Fraction        // @implementation 类名
@synthesize numerator = _numerator, denominator = _denominator;
-(void) setNumerator: (int) n andDenominator: (int) d;
{
  _numerator = n;
  _denominator = d;
}
-(Fraction *) init
{
  if (self = [super init]){
  // super是指向父类的指针, super的值和self一样, Fraction中不仅有自己的成员变量, 还有父类中的内容, 因此初始化的时候, 要先初始化父类的内容, 然后再初始化自己本身的内容.
   _numerator = _denominator = 0;
  }
  return self;        // self是当前对象的地址, 也相当于一个成员变量
}

@end

// ---- program section ----主函数部分

int main (int argc, const char * argv[])
{

@autoreleasepool {            // 为自动释放池在内存中保留了空间

Fraction *myFraction = [[Fraction alloc] init];        // 声明一个类的对象,分配内存空间并初始化
   // OC不允许类的对象创建在栈里, 自己写的类的对象只能创建在堆里
       // [Fraction alloc]这个表达式创建一个Fraction的对象在堆空间,表达式的值是该对象的地址, myFraction只是对象的指针
                           // 或者使用 Fraction *myFraction = [Fraction new];
       [myFraction setNumerator: 1];       // 把消息发送给对象,调用setNumerator方法,传递一个参数为1.
   // 调用myFraction指向的对象的方法setNumerator, 
       // 对象的地址(不是指针)调用对象的方法, (地址是常量, 指针是变量)
       // 也叫做给对象发送setNumerator消息

// OC完全兼容C; OC有自己专用的字符串, 同时也兼容C的字符串    
       NSLog(@"The value of myFraction is: ");      // 显示, @表示NSString型字符串对象, 不加为普通字符串    
   }
   return 0;
}

2.不可变字符串
   OC的字符串是一个对象, 它的类型是NSString类.
   OC所以会使用自己专有的字符串, 因为这个字符串是个对象, 有很多的方法, 比外来函数如strlen等更方便, 更面向对象.
   NSString * str = @"Hello World!";
   // @"Hello World!"这个表达式表示在只读数据段里, 创建了一个NSString的对象, 内容是Hello World!, 表达式的值是该对象的地址, 只有字符串可以这样创建一个对象
  // NSString的对象是不可变的
  // NSMutableString的对象是可变的

NSString * str2  = [[NSString alloc] initWithString: str];

NSString * str3 = [[NSString alloc] initWithUTF8String:"HEllo World!"];
  //用C的字符串创建OC的字符串, 完成C的字符串转换成OC的字符串
  char * cString = [@"Objective-C String" UTF8String];        // 将OC字符串转换为C字符串

NSString * str4 = [[NSString alloc] initWithFormat:@"hello %c %d %f", ‘A‘, 3, 3.14];
  // 根据格式符, 拼接创建一个字符串, 最强大

还有类方法[NSString stringWithString: str];
      [NSString stringWithUTF8String:"hello"];
      [NSString stringWithFormat:@"hello %d", 5];

characterAtIndex
 length        // 没有尾0

转换大小写:
   uppercaseString        // 全大写
   lowercaseString        // 全小写
   capitalizedString    // 单词首字母大写
 比较大小:
    isEqualToString
    compare
    hasPrefix:        // 是否包含前缀
    hasSuffix:        // 是否包含后缀

查找:
    rangeOfString           查找字符串中子串的范围, range.location  range.length

提取子串:
    subStringToIndex
    subStringFromIndex
    subStringWithRange

结构体的对象能存储在栈里, 而类的对象不能存储在栈里.

3. 可变字符串
  NSMutableString : NSString
  NSString 的方法 NSMutableString 也能用
  传参的时候可以传NSString * 也可以传 NSMutableString *

setString  设置或替换当前字符串内容

增:
      追加: appendString      appendFormat
      插入: insertString:  atIndex:
  删:
   deleteCharactersInRange
   生成range的函数NSMakeRange(2, 4);
  改:
   replaceCharactersInRange:  withString:
  查:
   rangeOfString

4.类别
  只有OC才有类别  (categoryName)
  类别就是类的升级补丁, 可以被继承
  类别不能用来添加成员变量, 只能添加方法(包括类方法和成员方法)

5.不可变数组
  数组的元素是任意的对象, 不仅仅局限于字符串, 数组中只装了对象的地址. 相当于指针数组.
  和C中的数组不同, 元素可以是不同类型的对象, 在结构上讲, 它是一个链表.
  initWithObjects

使用%@打印的都是对象, 而且这个类都要有一个description方法
  -(NSString *) description;        // description方法只能这样写, 打印的是该方法的返回值, 对中文支持不好

直接遍历:
   NSLog(@"%@", arrayName);
  枚举法遍历:  
   用当前数组创建一个枚举器(NSEnumerator *)enumerator = [array objectEnumerator], 然后调用枚举器的nextObject方法, 返回数组中每个元素的地址.
  快速枚举法:
   for (id obj in arrayName){}    
   专门用于枚举数组的for, 和平常的for不是一个. 每次循环得到一个数组元素的地址.
  循环遍历:    
   objectAtIndex:    // 返回数组中一个元素的地址    
   indexOfObject:    // 某元素的下标    
      count        // 元素个数

[array containsObject: ]    // array中是否包含某个元素

componentsJoinedByString:    // 将数组中的元素组合起来
  componentsSeparatedByString:    // 分割字符串
  componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString: ]    // 使用字符分割字符串

6.可变数组
  初始化:
    initWithArray
    [arrayName  ObjectsAtIndexes]
    setArray

枚举法遍历的时候不允许修改其中的元素及个数和顺序, 快速枚举法也不可以, 但是逆序枚举的时候reverseObjectEnumerator可以修改

增加:
    addObject
    insertObject:  atIndex:

删除:
    removeObjectAtIndex
    removeObject

exchange   replace

排序:
    sortUsingSelector: @selector(isBigThan:)    // selector叫做选择器, 相当于成员方法的函数指针

7.SEL
 SEL是一个类型, 用SEL声明的一个变量, 里面装的是消息, 如: SEL s = @selector(methodName);  // 有参数要写:, 即完整的方法名
 @selector实际上返回的是名字ID; 作用是使方法可以赋值, 因此就可以传参, 即可以作为函数的参数来使用
 编译器给每一个方法都分配了一个编号(0, 1, …), 叫名字ID, 不同的类中, 只要方法的名字相同, 名字ID就相同, 不同的是每个方法的入口地址不一样
 [objectName performSelector: s withObject: ]    // 还原方法, 并调用, 有1个参数, 就加1个withObject, 最多支持2个
 repondesToSelector:@selector()   //对象能否响应selector指定的方法

8.Class
 Class也是一个类型, 是装类的变量, 如: Class cls = [ClassName class];   之后就可以用cls代替ClassName
 作用是使类可以赋值, 因此就可以传参, 用于isKindOfClass: [ClassName class]    // 是否是ClassName类或其子类
 isSubclassOfClass:[ClassName class]

9.字典
  NSMutableDictionary: NSDictionary
  initWithObjectsAndKeys:
  // 字典中的成员称为键值对, @"One"和@"1"组成一个键值对, @"One"称为值(Value), @"1"称为键(Key);
  // 键和值都是任意对象, 不过, 键往往使用字符串, 字典里装的只是键和值的地址, 值可以重复, 但是键不能重复, 为同一个key设置value时, 将会替换掉原始的value
  // 字典中的键值对没有顺序, 没有第一个第二个之说, 和数组不一样, 结构上也是链表
  ObjectForKey        // 可以迅速通过key来找到一个值(value)
  count            // 键值对的个数
  枚举法遍历有两种, 通过键枚举遍历(keyEnumerator), 通过值枚举遍历[objectEnumerator], 快速枚举法, 遍历到的是键,
  setObject: forKey:    
  removeObjectForKey

10.setter, getter, @property
  在setter, getter中, 可以使用.运算符, 如果是赋值, 是使用set方法, 如果是使用私有变量, 是使用get方法
  @property (readonly)    // 表示只创建get方法, 不创建set方法, 没有write only
  (atomic)    // 原子操作, 有这个参数时, 在这个线程运行结束之前, 不允许其他线程使用我已用的资源, 正常情况下, 线程是可以使用同一个资源, 并且多个线程间可以交替的运行
  (nonatomic)    // 不必原子操作, 默认是原子操作的, 因此有时会加这个参数
  @property (getter = OtherName) int name; // 修改默认的getter名字name为OtherName, 使用的时候可以同时使用这两个名字
  @property (setter = setOther:)       // setter后面必须有冒号;
  (assign) 和 (readwrite) 都是默认的属性, 不需要写, 有时写上assign, 表示其他属性都不需要, 而不是忘记写了其他属性
  // 如:@property NSString * name; 这时会有错误, 写成@property (assign) NSString * name; 就没有错误了
  // 多个属性之间, 使用逗号隔开
  (copy)  (retain)    // 这样声明对象的时候, 要在dealloc中加入release.
  // NSString使用copy, 其他的对象都用retain, 基本数据类型都是默认的assign

11.继承
  多态: 同一名字的方法, 做不同的事情, 有重载, 重写, 虚函数
  封装: 把复杂的功能, 封装成相对简单的代码, 如函数, 宏, @property, 结构体, 类
  private: 不能被子类继承, 不能被外部函数访问, 但是继承的时候, 子类也给private分配了空间, 
  protected: 能被子类继承, 不能被外部函数访问
  public: 可以被子类继续, 可以被外部函数访问
  C++继承时的方式也有三种, 但是和变量的权限完全不一样. private继承, 继承来的成员, 都变成私有的; protected继承, 继承来的成员, 都变成受保护的; public继承, 继承来的成员, 原本是什么权限, 还是什么权限.
  OC中只有公有继承, 子类继承之后, 多了一些变量, 就叫做派生, 子类的成员分为继承和派生两部分. 
  继承的时候是完整的继承了父类的全部, 使用继承自父类的方法, 可以去访问父类的私有成员, 虽然子类中没有父类的私有成员, 但确为其分配了空间

NSString, NSArray, NSDictionary这三个类不能被程序员自己继承

虚函数: OC中的所有成员方法都是虚函数,
   1) 父类的指针可以指向子类的对象
   2) 调用方法时, 不看指针只看对象
  不同事物被同一事件触发, 产生不同的响应

12.
栈: (函数, 结构, 变量等存储的地方)
堆:
数据段:
只读数据段:
代码段: (告诉cpu做什么, 然后在栈里面开始做)(函数等结构的入口地址都是在代码段的, 实体是存储在栈中的)
  压栈

13.内存管理
  就是堆空间的创建和释放问题, C语言在释放堆的时候, 有不足, 因此OC有自己的内存管理
  给一个对象分配一个堆, 只是将这处堆空间设为私有的, 将这处对象释放后, 将这处堆空间设为公有的, 但堆中存储的内容还存在, 没有丢失, 除非之后再给这个堆空间覆盖(重新赋值).
  C语言中不释放会发生内存泄露, 释放两次, 会出现重复释放, free(p)的时候, 释放的是p指向的堆空间, C中也有类似于OC的计数器, 叫PV操作(加减操作), 不过需要自己写计数器, 和释放函数
  alloc时, 自动将计数器设为1, retain计数器加1, release减1, retainCount查看引用计数 
  内存管理黄金法则:
     1.(公认) 当使用alloc, retain, copy, mutableCopy, new "创建"一个对象, 或增添一个指针, 则必须使用release或autorelease进行"释放".
     2.(非公认) 每个指针做自己的内存管理, 每个类做自己的内存管理, 各人顾各人.

放在只读数据段中的对象, 计数器被设置为负数(-1), retain遇见负数的时候, 什么也不会做, 不修改计数器, 因为只读数据段不能被修改
  -(void)dealloc; 析构方法, 没有参数, 不能重载  
  常量字符串的set方法, if (name != newName){ [name release]; name = [newName retain];}, 之后还要在dealloc中加入[name release]; [super dealloc];

autorelease, 将使用autorelease的对象放入最近的自动释放池中, 等池释放的时候, 才释放对象; 原则上, 除非万不得已, 不要使用autorelease. 在类方法中, 一般都是使用autorelease; 在get对象时, 最好也要使用, return [[name retain] autorelease];
  IOS系统下, 每个触发周期, 都会创建并释放一个自动释放池 
  还有一种就是ARC(自动管理内存)

14.协议
  协议是完成两个类之间通信的一种机制, 在两个类的对象之间传递信息.
  发送方持有协议, 接收方遵守协议.
  @protocol    <protocolName>       id <protocolName> delegateName;
  @required     // 遵守协议的类必须实现该方法, 默认的属性
  @optional    // 可选的
  协议中声明过的方法, 遵从协议的类可以不写声明, 直接写实现
  如果两个对象互为代理, 即互为引用, 若都计数, 会发生死锁; 所以当两个对象互为代理的时候, 若A->p = [B retain],(A对B强引用), 那么B->p = A,(B对A弱引用) 不要再计数.
  单向协议的时候, 如果协议没有单独放在一个文件中, 协议要放在发送方所在的协议中, 因为发送方有可能是接收方的成员, 如果协议放在接收方中, 头文件包含会形成一个环.
 conformsToProtocol:@protocol()

15.文件
1)关于文件本身的操作 (NSFileManager 文件管理器)
  [NSFileManager defaultManager]    // 声明一个NSFileManager对象
  [contentsOfDirectoryAtPath: error: &error]    // 浅度遍历, 查看当前目录下的内容, 返回值是数组; 如果没有错误, error返回nil, 否则, 会在堆中创建个NSError的对象, 并将该对象地址赋给error; 传地址, 就是为了修改地址中存的值
  [subpathsOfDirectoryAtPath: error: &error]    // 深度遍历, 不仅遍历当前目录的文件, 也遍历子目录下的内容
  createDirectoryAtPath: withIntermediateDirectories: NO attributes: nil error: &error];
  // 创建一个目录; 第二个参数, 如果传入YES, 会自动创建中间目录(mkdir -p), 如果传入NO, 只要中间目录不存在, 就报错; 第三个参数, 设置该目录的属性, 传入nil, 为一般(默认缺省)属性;
  createFileAtPath: contents: attributes:     // 创建文件
  字符串自带一个dataUsingEncoding:  将一个字符串存入NSData中, data.bytes读取data中的内容
  removeItemAtPath: error:&error        // 删除文件或目录
  copyItemAtPath: toPath: error:        // 拷贝, 文件名必须写全
  attributesOfItemAtPath: error:        // 获得文件属性, 放在字典中
  fileExistsAtPath:                // 判断文件是否存在
  fileExistsAtPath: isDirectory:        // 判断文件是否存在, 并且是否是文件夹

2)关于文件内容的操作 (NSFileHandle 文件句柄)
  从文件到内存是读, 从内存到文件是写
  file pointer(指针)文件指针    file descriptor(数字)文件描述符    file handle(对象)文件句柄, 往文件句柄里写就是往文件中写
  [NSFileHandle fileHandleForReadingAtPath: ]    // 以只读的方式打开文件生成文件句柄
  readDataToEndOfFile
  readDataOfLength    // read读两次的时候, 不是从头再开始读, 而是每次读都接着上次读到的位置往下读
  字符串的方法: initWithData: encoding    // data转字符串    dataUsingEncoding: // 字符串转data
  fileHandleForWritingAtPath:  // 以只写的方式打开文件, 如果文件不存在, 则创建文件, 在C中"w"会清空原文件, OC是一个一个的覆盖
  writeData:         // 第一次从头开始写, 第二次接着往下写
  seekToEndOfFile    // 将读写指针置到文件尾
  seekToFileOffset:    // 将读写指针置到文件指定位置, 0就是文件首
  truncateFileAtOffset:  // 清空(截断)一个文件, 只剩下前面n个字节
  fileHandleForUpdatingAtPath:        // 读写操作

16.NSDate
  NSDate * date = [NSDate date];    // 使用当前时间创建一个date对象
  [NSDate dateWithTimeIntervalSinceNow: seconds]    // 用一个时间间隔(seconds)来表示过去或未来的某一时间
  [[NSDate date] timeIntervalSinceDate: date]        // 将日期与保存在date中的日期进行比较   
  [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: ]];    // 让应用程序休眠一段时间

NSDateFormatter    // 将日期转化为完全格式化的字符串
  dateFormatter.dateFormat = @"MM/dd/YY HH:mm:ss";
  [dateFormatter stringFromDate: [NSDate date]];

[NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector() userInfo: nil repeats: YES]  
  // 1秒后触发此定时器, 并不断循环下去, 直到定时器被禁用([timer invalidate])

时间: 2024-10-11 10:29:55

OC方面的基础笔记摘录的相关文章

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

网络基础笔记——OSI七层模型

OSI七层模型 由于整个网络连接的过程相当复杂,包括硬件.软件数据封包与应用程序的互相链接等等.如果想要写一支将联网全部功能都串连在一块的程序,那么当某个小环节出现问题时,整只程序都需要改写.所以我们将整个网络分成数层,每层都有自己独立的功能,而且每层的代码都可以独立撰写,因为相互之间不会干扰.如此一来,当某个小环节出现问题时,只要将该层的代码改写即可.并且这样可以让整个网络层次更加的清晰. 在网络上传输信息就像是一个发包裹的过程,从己方的应用程序开始往第七层的包裹里塞数据,再依次塞到第一层的包

[Java基础笔记]数组

Java基础笔记 定义数组: int[] numbers = new int[100]; //方法一 double[] num = new double[10]; int[][] a = new int[2][5]; 通过new创建的数组,元素默认值为0(0.0) int[] scores = {5,4,33,12,46}; //方法二 int[][] a = { //位数不足,自动补0 {5,3,2,1,6}, {10,12,14,15}, }; 数组特性:存储的都是同类型数据:长度定义后不可

C# 基础笔记(第一篇)

C#基础 概念:.net与c#.net/dontnet:一般指.net framework框架,一种平台,一种技术c#(charp):一种编程语言,可以开发基于.net的应用. *java既是一种技术又是一种编程语言.                           .net都能干什么?开发桌面应用程序   Winforminternet应用程序    Asp.net/webservice C/S:客户机(Client)/服务器模式(Server)B/S:浏览器(Browser)/务器模式(

我的LINUX基础笔记

Linux系统管理      1 Day   2014.5.23 su -name   切换用户passwd 密码   更改密码gnome-terminal    伪CLI   桌面终端程序1.查看内核版本uname -r    2.查看红帽系统版本cat /etc/redhat-rdlease3.查看LINUX标准分发版信息  lsb_release4.查看网卡的IP,MAX       ifconfig                       ifconfig eth 10.0.0.10

Nginx基础笔记

Nginx基础笔记 资源 安装 ubuntu下 编译安装 基本操作 HTTP基本配置 配置说明 配置文件目录结构 配置文件结构 模块 模块化 index模块 Log模块 Real IP模块 Access模块 Rewrite模块 Proxy模块 upstream模块 其他 配置静态化目录 负载均衡 控制页面缓存 nginx的内置变量 nginx小结 资源 资源 Nginx 官网 Nginx 官方下载地址 Nginx最佳实践配置项目 地址 Nginx Configuration wiki 教程 ag

MYSQL基础笔记(三)-表操作基础

数据表的操作 表与字段是密不可分的. 新增数据表 1 Create table [if not exists] 表名( 2 字段名 数据类型, 3 字段名 数据类型, 4 字段n 数据类型 --最后一行不需要加逗号 5 )[表选项]; If not exists:如果表名不存在,那么就创建,否则不执行创建代码,实现检查功能. 表选项:控制表的表现 1.字符集:charset/character 具体字符集:--保证表中数据存储的字符集. 2.校对集:collate 具体校对集: 3.存储引擎:e

REDIS基础笔记

Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布/订阅模式 Python中使用Redis 实际实例 管理 其他 资源链接 推荐书籍:<Redis入门指南> 资源列表: redis命令速查command | CMD索引-中文 | CMD树-中文 redis源码github 下载地址redis.io The Little Redis book 入口

php代码审计基础笔记

出处: 九零SEC连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059 ---------------------------------------------------------- team:xdsec&90sec author:wilson blog:http://blog.wils0n.cn/ 文章链接:wilson's blog_php代码审计基础笔记[求人气~~] ----------------------