Ojbective-C基础教程

OC基础

一、Foundation

[NSNull 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 :定时器

     以上为不可变类型,其对可变类型如: NS Mutable String 、 NS Mutable Integer 、 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;

  • 对象拷贝
     对象要具备复制功能,必须实现协议或者协议,自定义对象实现协议的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的名称)(参数类型) = ^返回值类型(参数) {...};
//2
returnType (^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


你可能感兴趣的:(iOS开发)