Foundation Framework
1. Values and collection classes
2. User defaults
3. Archiving 归档
4. Notifications
5. Undo manager
6. Tasks, timers, threads
7. File system, pipes I/O, bundles
NSObject
root class
实施许多基本操作:Memory management; Introspection; Object equality.
NSString
基本目的是将string 支持统一代码化(Unicode):unicode is a coding system which represents all of the world's languages;
在 Cocoa Touch 中一致使用,而不是 "char *";
最常使用的类;
轻松支持任何语言通过 Cocoa.
字符串常量 String Constants
C语言中:“simple”
Obj-C 中:@“just as simple”
NSString *aString = @"Hello World!"
字符串的格式:
与printf 相似,但是需要加 %@ 在 objects 前
NSString *aString = @"Johnny";
NSString *log = [NSString stringWithFormat: @"it's '%@' ", aString];
输出结果是:it's 'Johnny'
同样适用于 logging: NSLog(@"I am a %@, I have %d items", [array className], [array count]);
输出结果像这样这样:I am a NSArray, I have 5 items
NSString 经常需要修改一个已经存在的字符串,使其成为一个新的字符串:
(NSString *)stringByAppendingString: (NSString *)string;
(NSString *)stringByAppendingFormat: (NSString *)string;
(NSString *)stringByDeletingPathComponent;
例子:
NSString *myString = @"Hello";
NSString *fullString;
fullString = [myString stringByAppendingString: @"world!"];
fullString是 Hello world!
常见的NSString methods函数:
(BOOL)isEqualToString: (NSString *)string;
(BOOL)hasPrefix: (NSString *)string;
(int)intValue;
(double)doubleValue;
例子:
NSString *myString = @"Hello";
NSString *otherString = @"449";
if ([myString hasPrefix: @"He"]){
程序在这里执行
}
if ([otherString intValue] > 500){
程序在这里不执行
}
NSMutableString
NSString的子类;
允许字符串被修改;
常见的 NSMutableString 函数:
+(id)string;
- (void)appendString: (NSString *)string;
- (void)appendFormat: (NSString *)format, ...;
例子:
NSMutableString *newString = [NSMutableString string];
[newString appendString: @"Hi"];
[newString appendFormat: @", my favorite number is: %d", [self favoriteNumber]];
Collections:
Array: 有顺序的元素集合
Dictionary: key-value pairs 集合
Set: 乱序的unique元素集合
相同的枚举机制;
不变和可变;
不变集合可以被分享没有副作用: prevents unexpected changes; mutable objects typically carry a performance overhead.
NSArray:
常见的 NSArray 函数:
+arrayWithObjects: (id) firstObj, ...; // 结束时,加nil
- (unsigned)count;
- (id)objectAtIndex: (unsigned) index;
- (unsigned)indexOfObject: (id)object;
如果没有找到index 则返回 NSNotFound.
NSArray *array = [NSArray arrayWithObjects: @"Red", @"Blue", @"Green", nil];
if ([array indexOfObject: @"Purple"] == NSNotFound){
NSLog (@"No color purple");
}
NSMutableArray:
是NSArray的子类;
常用的 NSMutableArray 函数:
+ (NSMutableArray *)array;
- (void)addObject: (id)object;
- (void)removeObject: (id)object;
- (void)removeAllObjects;
- (void)insertObject: (id)object atIndex: (unsigned)index;
NSMutableArray *array = [NSMutableArray array];
[array addObject: @"Red"];
[array addObject: @"Green"];
[array addObject: @"Blue"];
[array removeObjectAtIndex: 1];
NSDictionary:
常用的 NSDictionary 函数:
+ dictionaryWithObjectsAndKeys: (id)firstObject,...;
- (unsigned) count;
- (id) objectForKey: (id)key;
如果找不到任何object 给了key, 返回nil.
NSDictionary *colors = [NSDictionary dictionaryWithObjectsAndKeys: @"Red", @"Color 1", @"Green", @"Color2", @"Blue", @"Color3", nil];
NSString *firstColor = [colors objectForKey: @"Color 1"];
if ([colors objectForKey: @"Color8"]){
这里不执行
}
NSMutableDictionary:
是NSDictionary 的子类;
常用的 NSMutableDictionary 函数:
+ (NSMutableDictionary *) dictionary;
- (void)setObject: (id)object forKey:
- (void)removeObjectForKey: (id)key;
- (void)removeAll Objects;
NSMutableDictionary *colors = [NSMutableDictionary dictionary];
[colors setObject: @"Orange" forKey: @"HighlightColor"];
NSSet:
无序集合对于不同的对象;
常用的 NSSet 函数:
+ setWithObjects: (id)firstObj,...; //nil 结尾
- (unsigned)count;
- (BOOL)containsObject: (id)object;
NSMutableSet:
是 NSSet 的子类;
常用的 NSMutableSet 函数:
+ (NSMutableSet *)set;
- (void)addObject: (id)object;
- (void)removeObject: (id)object;
- (void)removeAllObjects;
- (void)intersectSet: (NSSet *)otherSet;
- (void)minusSet: (NSSet *)otherSet;
Enumeration:
和在集合中枚举对象的方法一样;
用NSArray, NSDictionary, NSSet, etc.
NSArray *array = ...; // assume an array of People objects
例子:
// old school
Person *person;
int count = [array count];
for (i=0; i < count; i++){
person = [array objectAtIndex: i];
NSLog ([person description]);
}
// new school
for (Person *person in array){
NSLog([person description]);
}
其余的类:
NSData/NSMutableData: 任意设置字节
NSDate/NSCalendarDate: 时间和日期
Methods and Selectors:
专业术语:
Message expression: [receiver method: argument]
Message: [receiver method: argument]
Selector: [receiver method: argument]
Method: the code selected by a message
Methods, Messages, Selectors:
Method: 与对象相关连的行为
- (NSString *)name
{
//implementation
}
- (void)setName: (NSString *)name
{
//implementation
}
Selector:
一个方法的名称;
包括冒号,为了引出argument;
并不实际的包括 argument 或指出 types;
selector可以叫做选择器,指的是对象的方法,也可以理解为C 语言里面的函数指针,在面向对象里面的对应概念。
@selector(xxxx)的作用是找到名字为xxxx的方法,一般用于[a performSelector: @selector(b)],就是说去调用a 对象的 b 方法,和[a b]的意思一样,但是这样更动态些。@selector(xxxx)返回的类型是SEL,看方法说明的时候如果参数类型是SEL,那么就是要接受@selector(xxxx)返回的值的那种了。
SEL mySelector = @selector(name);
SEL anotherSelector = @selector(setName);
SEL lastSelector = @selector(doStuff: withThing: andThing: );
SEL的定义:
typedef struct objc_selector *SEL;
具体这 objc_selector结构体是什么取决于使用GNU的还是Apple的运行,可以看作是方法的名字,它并不是一个指向具体方法实现。对于所有的类,只要方法名是相同的,产生的selector都是一样的。
简而言之,@selector() 就是取类方法的编号,他的行为基本可以等同C语言中的函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而obj-c的类不能直接应用函数指针,这样只能做一个@selector语法来取。
它的结果是一个SEL类型,这个类型本质是类方法的编号(函数地址)。
1. 取得selector值
C函数指针:
int add(int val){
return val+1;
}
int (*c_func)(int val); //定义一个函数指针变量
c_func = add; //把函数addr地址直接赋给c_func
Obj-C的选择器:
@interface foo
-(int)add:int val;
@end
SEL class_func; //定义一个类方法指针
class_func = @selector(add:int);
注意:@selector是查找当前类的方法,而[object @selector(方法名:方法参数..)] 是取object对应类的相应方法;
查找类方法时,除了方法名,方法参数也算查询条件之一;
可以用字符串来找方法SEL 变量名 = NSSelectorFromString(方法名字的字符串);
可以运行中用SEL变量反向查出方法名字字符串:NSString *变量名 = NSStringFromSelector(SEL参数).
2. 执行selector值
取得相应值后,怎么处理SEL值呢,这一点与函数指针一样,就是执行它
函数指针执行,有下面几种等效形式:
*c_func(10);
c_func(10);
SEL变量的执行,用performSelector方法来执行:
[对象 performSelector: SEL变量 withObject: 参数1 withObject: 参数2];
3. selector的应用场合
selector本质是跟C的回调函数一样,主要用于两个对象之间进行松耦合的通讯,这种方法很多开发环境用到。
Message:
The act of performing a selector on an object;
如果需要,可以带 arguments.
NSString *name = [myPerson name];
[myPerson setName:@"New Name"];
Selectors identify methods by name:
A selector has type SEL:
SEL action = [button action];
[button setAction: @selector(start:)];
概念上和函数指针相似;
选择器包括名字和所有的冒号:(void)setName: (NSString *)name age: (int)age;
我们有一个选择器的例子:SEL sel= @selector(setName:age:);
Work with selectors:
我们可以判断一个对象是否可以相应给定的选择器
id obj;
SEL sel= @selector(start:);
if ([obj respondsToSelector: sel]){
[obj performSelector:sel withObject:self];
//equivalent to [obj start:self];
//For multiple arguments use ... withObject: withObject;
}
This sort of introspection and dynamic messaging underlies many Cocoa design patterns.
-(void)setTarget: (id)target;
-(void)setAction: (SEL)action;
More information on Selectors:
Selectors are unique identifiers that replace the name of methods when compiled;
选择器是独一无二的标志当编译的时候会替代方法的名字;
Compiler writes each method name into a table and associates it with this unique id (the selector);
编译器把每个方法的名字写入到一个地方,并且和它独一无二的id相匹配,即选择器;
The compiler assigns all method names a unique selector or SEL (the selector type)
——Every "method name" whether it is a part of your class or another class has an entry in that table with a unique selector value
编译器配置所有的方法名字一个独一无二的选择器或SEL
——每个“方法名字”,不管它是不是类的一部分或另一个类,有一个入口到这个地方,这个入口是独一无二的选择器的值