Objective-C代码的文件扩展名
1、.h —–头文件。头文件包含类,类型,函数和常数的声明。
2、.m —–源代码文件。这是典型的源代码文件扩展名,可以包含 Objective-C 和 C 代码
3、.mm —–源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。
消息传递:对象之间互相传递消息,调用方法视为对对象发送消息,所有方法都被视为对消息的回应
// "发提交一个fly的消息给car对象",fly是消息,而car是消息的接收者。car收到消息后会决定如何回应这个消息,若car类别内定义有fly方法就运行方法内之代码,若car内不存在fly方法,则程序依旧可以通过编译,运行期则抛出异常。
[car fly];
字符串:普通的双引号字符串前放置一个@符号
//NSString类提供了字符串的类包装,大多数框架把字符串传递给NSString对象。
NSString* myString = @"My String\n";
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];
类:是 Objective-C 用来封装数据,以及操作数据的行为的基础结构
// 1、定义(interface)部分包含了类声明和实例变量的定义,以及类相关的方法。
// 以关键字@interface作为开始,@end作为结束。
@interface MyObject : NSObject { // :后是父类的名字
int memberVar1; // 实体变量
id memberVar2;
}
// 方法前面的 +/- 号代表函数的类型
+(return_type) class_method; // 类方法
-(return_type) instance_method1; // 实例方法:在类的具体实例中运行
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
// 宣告方法
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue;
[myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 呼叫方法*/
// 这个方法的签名是setColorToRed:Green:Blue:。每个冒号后面都带着一个float类别的参数,分别代表红,绿,蓝三色
@end
2、实现(implementation)部分包含了类方法的实际代码。
// 实现区块则包含了公开方法的实现,以及定义私有(private)变量及方法。
// 以关键字@implementation作为区块起头,@end结尾。
@implementation MyObject {
int memberVar3; //私有实体变量
}
+(return_type) class_method {
....
}
-(return_type) instance_method1 {
....
}
// 名称内的冒号(:)代表参数传递
-(return_type) instance_method2: (int) p1 {
....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
....
}
@end
创建对象:需通过alloc以及init两个消息。alloc的作用是分配内存,init则是初始化对象。 init与alloc都是定义在NSObject里的方法,父对象收到这两个信息并做出正确回应后,新对象才创建完毕。以下为范例:
MyObject * my = [[MyObject alloc] init];
//在Objective-C 2.0里,若创建对象不需要参数,则可直接使用new
MyObject * my = [MyObject new];
方法:方法声明包括方法类型标识符,返回值类型,一个或多个方法标识关键字,参数类型和名信息。
// 下图展示 insertObject:atIndex: 实例方法的声明。声明由一个减号(-)开始,这表明这是一个实例方法。方法实际的名字(insertObject:atIndex:)是所有方法标识关键的级联,包含了冒号。冒号表明了参数的出现。如果方法没有参数,你可以省略第一个(也是唯一的)方法标识关键字后面的冒号。本例中,这个方法有两个参数。
-(void) insertObject:(id)anObject atIndex:(NSUInterger)index;
// 接收消息的对象在左边,消息(包括消息需要的任何参数)在右边,给myArray变量传递消息insertObject:atIndex:消息
[myArray insertObject:anObj atIndex:0];
// 消息的嵌套
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
属性
// 声明
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
// 访问
@implementation Person
@synthesize name;
@dynamic age;
-(id)initWithAge:(int)initAge
{
age = initAge; // 注意:直接赋给成员变量,而非属性
return self;
}
-(int)age
{
return 29; // 注意:并非返回真正的年龄
}
@end
// 属性可以利用传统的消息表达式、点表达式或"valueForKey:"/"setValue:forKey:"方法对来访问。
/* 消息表达式 */
Person *aPerson = [[Person alloc] initWithAge: 53];
/* 点表达式 */
aPerson.name = @"Steve"; // 注意:点表达式,等于[aPerson setName: @"Steve"];
/* 不清楚 */
NSLog(@"Access by message (%@), dot notation(%@), property name(%@) and direct instance variable access (%@)",
[aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);
// 为了利用点表达式来访问实例的属性,需要使用"self"关键字:
-(void) introduceMyselfWithProperties:(BOOL)useGetter
{
NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name));
}
// 类或协议的属性可以被动态的读取。
int i;
int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList([aPerson class], &propertyCount);
for ( i=0; i < propertyCount; i++ ) {
objc_property_t *thisProperty = propertyList + i;
const char* propertyName = property_getName(*thisProperty);
NSLog(@"Person has a property: '%s'", propertyName);
}
快速枚举
// 使用快速枚举
for (Person *p in thePeople) {
NSLog(@"%@ is %i years old.", [p name], [p age]);
}