Ojbective-C基础教程

来源:互联网 发布:java全栈开发工程师 编辑:程序博客网 时间:2024/04/20 20:51

OC基础

一、Foundation

[NSNull null] => <null> 表示NSNull对象

nil => (null) 表示nil值

  • 基础
  1. NSString:字符串
  2. NSInteger、NSUInteger 

  • 集合
  1. NSArray:数组,顺序存储,总不可存储基本数据类型,只能存放类的实例;需要把基础数据类型、结构体放入其中需要放入NSNumber\NSValue中进行封装
  2. NSSet:集合,hash无序,查找效率比NSArray高
  3. NSDictonary:字典

  • 数据封装
  1. NSNumber:主要是用来封装ANSI C内置的数据,比如char,float,int,bool,(NSInteger是基础类型,NSNumber是一个类)
  2. NSValue:主要用来封装数据结构,包括系统(CGPoint/CGSize等)和自定义
  3. NSData:主要是提供一块原始数据的封装,方便数据的封装与流动,比较常见的是NSString/NSImage数据的封装与传递。在应用中,最常用于访问存储在文件中或者网络资源中的数据。

  • 其他
  1. NSDate:日期、时间
  2. NSTimer :定时器

    以上为不可变类型,其对可变类型如:NSMutableString 、NSMutableInteger 、NSMutableArray

二、协议和委托

  1. 协议仅仅声明方法,用作接口,本身并不实现,遵循该协议的类则负责具体实现。@protocol、@required、@required
  2. 委托是一种避免对复杂的UIKit对象(比如缺省的UIApplication对象)进行子类化的机制。在这种机制下,您可以不进行子类化和方法重载,而是将自己的定制代码放到委托对象中,从而避免对复杂对象进行修改。

    比如:Student遵循_protocolDelegate协议,实现work方法;Student委托给Teacher,Teacher通过call_work使Student执行协议方法work

三、interface类

  • 初始化
  1. 如果实现一个初始化程序,确保调用超类的初始化;
  2. 如果超类的初始化不止一个方法,选择一个指定初始值设定;

  • 属性
    @property(nonatomic,strong) NSString *name;
    系统为我们自动生成的。命名规则是以_为前缀,加上属性名,如_name
  1. @property与@synthesize配对使用,用来让编译器自动生成与数据成员同名的方法声明
  2. C++中的.也可以用于访问属性:user.id 类似 [user id];user.id = 12类似[user setId:12]; 
@property特性:分为三类,分别是:
原子性
atomic(默认) 线程安全
nonatomic 非线程安全(nonatomic比atomic速度要快)
存取器控制
readwrite(默认)同时拥有setter和getter。
readonly 只有getter
内存管理
assign(默认)表示单纯的复制,
retain:在setter方法中,需要对传入的对象进行引用计数加1的操作
strong:是retain的一个可选的替代。strong跟retain的相同(语意上更好更能体现对象的关系)
weak:在setter方法中,需要对传入的对象不进行引用计数加1的操作。(就是对传入的对象没有所有权)
copy:与strong类似,但区别在于实例变量是对传入对象的副本拥有所有权,而非对象本身。

  • 类目
    使用类目,为现有的类NSString扩展方法,是新方法成为类的一部分,且子类也能继承
类目的不足:
  1. 类目还可以覆写现有类的方法。覆写后,原始方法则无法调用。
  2. 类目不能为类扩展实例属性。

  • 方法
  1. 重载 方法description,实现类指针打印的描述字符串;
  2. 单例模式:重载实现类方法allocWithZone,(实现限制方法,限制这个类只能创建一个对象)

四、内存管理

  1. init\alloc\copy\retain之后需要有相互对应的release
  2. 其他方法获取一个对象(一般是autorelease)如arrayWithCapacity、arrayWithObjects是自动释放不需要release;

  • 对象拷贝
    对象要具备复制功能,必须实现<NSCopying>协议或者<NSMutableCopying>协议,自定义对象实现协议的CopyWithZone方法/MutableCopyWithZone方法;常用的可复制对象有:NSString、NSMutableString、NSArray等;
拷贝方法:
  1. copy:产生对象的副本是不可变的
  2. mutableCopy:产生的对象的副本是可变的
浅拷贝和深拷贝
  1. 浅拷贝值复制对象本身,对象里的属性、包含的对象不做复制(默认)
  2. 深拷贝则既复制对象本身,对象的属性也会复制一份

五、KVC

  1. 键值:forKey/valueForKey
  2. 键路径:forKeyPath/valueForKeyPath
  3. 运算:左侧指定集合的运算;需要解析字符串路径,所以性能慢

  • NSPredicate谓词

六、数据持久化 归档

  1. NSKeyedArchiver
  2. NSKeyedUnarchiver

七、文件管理

  • 沙盒
    路径:~资源库/Application Support/iPhone Simulator/文件夹
  1. Documents:程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
  2. Library:系统文件,存储程序的默认设置或其它状态信息;Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
  3. tmp:临时文件的地方。App重启会被清空。

  • 文件操作

  1. NSFileManager 是一个单例类 (全局的能被整个系统访问到)对文件进行管理的各种操作(遍历\创建\拷贝\移动\删除)
  2. NSFileHandle 操作系统返回给我们程序的文件指针,用NSData类型的二进制数据,对文件进行读写的



OC进阶

一、语法

静态分析器:

1、函数对象释放检查:NS_RETURNS_RETAINED\NS_RETURNS_NOT_RETAINED
2、不放回对象:CLANG_ANALYZER_NORETURN

instancetype和id的异同

1、相同点
都可以作为方法的返回类型
2、不同点
①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
②instancetype只能作为返回值,不能像id那样作为参数,比如下面的写法:

二、利用arc4random_uniform()产生随机数

Objective-C 中有个arc4random()函数用来生成随机数且不需要种子但是这个函数生成的随机数范围比较大,需要用取模的算法对随机值进行限制,有点麻烦。其实Objective-C有个更方便的随机数函数arc4random_uniform(x),可以用来产生0~(x-1)范围内的随机数,不需要再进行取模运算。如果要生成1~x的随机数,可以这么写:arc4random_uniform(x)+1

三、消息处理方法performSelector: withObject:和直接调用的区别

    Objective-C中调用函数的方法是“消息传递”,这个和普通的函数调用的区别是,你可以随时对一个对象传递任何消息,而不需要在编译的时候声明这些方法。所以Objective-C可以在runtime的时候传递人和消息。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {

NSLog(@"Logs %@ then %@", first, second);

}

然后调用它

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second" afterDelay:1.5];

  • 1、performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。如果fooFirstInput:secondInput不存在,那么直接调用 在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃);Cocoa支持在运行时向某个类添加方法,即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用。所以有时候如果使用了performSelector,为了程序的健壮性,会使用检查方法

- (BOOL)respondsToSelector:(SEL)aSelector;

  • 2、直接调用方法时候,一定要在头文件中声明该方法的使用,也要将头文件import进来。而使用performSelector时候, 可以不用import头文件包含方法的对象,直接performSelector调用即可。


  • afterDelay 是一种dispatch_after()函数,支持在未来的某个时间执行




四、如何在Objective-C中定义代码块(Block)

1、作为变量

//1返回值类型 (^block的名称)(参数类型) = ^返回值类型(参数) {...};//2returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

2、作为属性

//1@property (nonatomic, copy) 返回值类型 (^block的名称)(参数类型);//2@property (nonatomic, copy) returnType (^blockName)(parameterTypes);

3、作为方法声明的参数

//1- (void)方法名:(返回值类型 (^)(参数类型))block的名称;//2- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;

4、作为方法实现的参数

//1[对象/类 方法名:^返回值类型 (参数) {...}];//2[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];

5、作为typedef

//1typedef 返回值类型 (^类型名称)(参数类型);类型名称 block的名称 = ^返回值类型(参数) {...};//2typedef returnType (^TypeName)(parameterTypes);TypeName blockName = ^returnType(parameters) {...};


五、Grand Central Dispatch (GCD) 

void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
    该函数接收一个dispatch_once用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块,对于本例就用于shared实例的实例化。
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的
  1. + (AccountManager *)sharedManager {
  2. static AccountManager *sharedAccountManagerInstance = nil;
  3. static dispatch_once_t predicate; dispatch_once(&predicate, ^{
  4. sharedAccountManagerInstance = [[self alloc] init];
  5. });
  6. return sharedAccountManagerInstance;
  7. }


六、UITableView全面解析

http://www.cnblogs.com/kenshincui/p/3931948.html#dataSource


0 0
原创粉丝点击