本文共 7438 字,大约阅读时间需要 24 分钟。
目录
#import//类比#include<> <>引用的是系统库;""引用自己定义的类int main(int argc,const char * argv[]){ @autoreleasepool{ //自动释放池 NSLog(@"Hello World!"); } return 0;}
Person *per = [[Person alloc]init];
Person *per = [Person new];
BNRStockHolding.h#import@interface BNRStockHolding:NSObject{ float _purchaseSharePrice; float _currentSharePrice; int _numberOfShares;}-(void)setPurchaseSharePrice:(float)p setCurrentSharePrice:(float)c... setNumberOfShares:(int)n;-(float)costInDollars;-(float)valueInDollars;@endBNRStockHolding.m:#import"BNRStockHolding.h"@implementation BNRStockHolding-(void)setPurchaseSharePrice:(float)p setCurrentSharePrice:(float)c... setNumberOfShares:(int)n{ _purchaseSharePrice=p; _currentSharePrice=c; _numberOfShares=n;}-(float)costInDollars{ return _purchaseSharePrice*_numberOfShares;}-(float)valueInDollars{ return _currentSharePrice*_numberOfShares;}@endmain函数:#import #import "BNRStockHolding.h"int main (){@autoreleasepool{ printf("My StockHolding:\n"); NSMutableArray *list=[[NSMutableArray alloc] init]; BNRStockHolding *A=[[BNRStockHolding alloc] init]; BNRStockHolding *B=[[BNRStockHolding alloc] init]; BNRStockHolding *C=[[BNRStockHolding alloc] init]; [A setPurchaseSharePrice:12 setCurrentSharePrice:14.5 setNumberOfShares:32]; [B setPurchaseSharePrice:17 setCurrentSharePrice:12.3 setNumberOfShares:25]; [C setPurchaseSharePrice:32 setCurrentSharePrice:27.5 setNumberOfShares:43]; [list addObject:A]; [list addObject:B]; [list addObject:C]; int i=1; for(BNRStockHolding *t in list) NSLog(@"第 %d 支股票的购入价为 %.2f,市值为 %.2f。",i++,[t costInDollars], [t valueInDollars]); } return 0;}
头文件以 @interface 开始,以 @end 结束。注意要在花括号中声明成员变量。
相当于 C++ 中的 this 指针,可以在类的方法中调用对象自身的方法;还可以将 self 做为实参传递给其他方法,以便其访问“当前的”对象。例如:
-(void)addYourselfToArray:(NSMutableArray*)theArray{ [theArray addObject:self];}
创建一个 NSString 字符串常量实例:
NSString *lament = @"Why me!";
用变量创建一个字符串实例:
NSString *dateString = [NSString stringWithFormat:@"The date is %@",now];
stringWithFormat:方法后面跟着一个格式字符串作为参数,这个格式字符串带有一个变量,变量的值类似与NSLog一样替换格式说明符。
NSUInterger charCount = [dateString length];
if([A isEqualToString:B]) NSLog(@"%@ and %@ are equal.",A,B);
NSString *A = @"That makes me so happy!";NSString *B =[A uppercaseString];
NSString listOfNames = @"..." //名单NSString name = @"Ward";NSRange match = [listOfNames rangeOfString:name];if(match.location == NSNotFound) NSLog(@"No match found!");else NSLog(@"Match!");
返回值 NSRange 是一个结构,包含 location 和 length 两个值。如果找不到目标子字符串则返回 NSNotFound。
与 NSString 相似,NSArray 也可以用字面常量语法创建实例。数组的内容写在方括号里,使用逗号分隔,前方带有@符号。
NSArray *dateList = @[now,tomorrow,yesterday];
NSArray 的实例是无法改变的,一旦 NSArray 实例被创建后,就无法添加或删除数组里的元素,也无法改变数组元素的顺序。
for(int i=0;i<[dateList count];i++){ NSLog(@" %@",dateList[i]);}
Objective-C 提供一种简化的 for 循环语法,称为快速枚举。省去了对数组计数的同时,高效地遍历数组的所有元素。
for(NSDate *d in dateList){ NSLog(@"Here is a date: %@.",d);}
类似于 C++ 中的 auto 遍历语法。
可以添加、删除或对元素重新进行排序。(NSMutableArray 是 NSArray 的子类)
NSMutableArray *dateList =[NSMutableArray array]; //创建空数组//将两个 NSDate 对象加入新创建的数组[dateList addObject:now];[dateList addObject:tomorrow];//将 yesterday 指针插入数组的起始位置[dateList addObject:yesterday atIndex:0];//删除 yesterday 指针[dateList removeObjectAtIndex:0];//快速遍历for(NSDate *d in dateList){ NSLog(@"Here is a date: %@.",d);}//在数组中查询是否有和 anObject 相等、相同的元素-(NSUInteger) indexOfObject:(id) anObject;-(NSUInteger) indexOfObjectIdenticalTo:(id) anObject;
创建:上述程序使用了 array 类方法来创建 NSMutableArray,等同于 [[NSMutableArray alloc] init];
添加:addObject :元素 方法自动在尾部添加元素,如果要将对象添加到一个特定的索引上,则可以使用 insertObject:atIndex:下标。
删除:removeObject:atIndex:下标 数组对象的计数也随之会减小。
遍历:不可在快速枚举过程中添加或者删除对象。
在自定义的类中删除实例变量,然后用两个属性重写存取方法的声明:
BNRStockHolding.h
#import<Foundation/Foundation.h>@interface BNRStockHolding:NSObject
@property (nonatomic) float purchaseSharePrice; @property (nonatomic) float currentSharePrice; @property (nonatomic) int numberOfShares; {-(void)setPurchaseSharePrice:(float)p setCurrentSharePrice:(float)c... setNumberOfShares:(int)n;
-(float)costInDollars;
-(float)valueInDollars;@end
.m文件中只需实现 costInDollars 与 valueInDollars 方法。
属性的特性会显示在 @property 后的括号中,属性第一可选项为
与多线程有关,原子性保证多线程的安全;省略此选项时默认为原子属性。
属性的第二可选项为
只读特性的值只能读取不能改写,编译器为其只生成取方法,不生成存方法;省略此选项时默认为读写属性。
使用属性标识的变量,在方法中使用到时,必须用 self.变量名
[mikey setWeightInKilos:96]; [mikey setHeightInMeters:1.8];
使用点调用的时候是在发送消息。
public 成员只能用 ->
#import "BNRPerson.h"
@interface BNREmployee:BNRPerson@property (nonatomic) unsigned int employeeID;
@property (nonatomic) unsigned int officeAlarmCode; @property (nonatomic) NSDate *hireDate; -(double)yearsOfEmployment;@end
其中 hireDate 属性是指向另一个对象的属性,属性值想对象的时候,需要对内存进行管理。
覆盖方法的时候只能改变方法的实现,没有必要在.h文件中声明,相应的声明在继承的父类中已经写出。方法的名称、返回类型及实参类型等都必须保持相同。
覆盖一个方法的时候。子类可以利用父类方法的结果,而不是整个替换。调用格式为:
[super 实例方法名]
-(float)bodyMassIndex{ float normalBMI = [super bodyMassIndex]; return normalBMI * 0.9;}
基本所有的类都继承自 NSObject。
NSObject 拥有很多方法,但是只有一个实例变量:isa 指针。指针类型为创建该对象的类。
给对象发送消息的时候,对象就会通过 isa 指针找到该对象的类查询是否有该消息名的方法,如果没有则查询它的父类。但是如果使用 super 指令,就等于告诉对象,从对象的父类开始查找与之匹配的指定的方法。
由于继承中子类只 import 了父类的头文件,所以看不到父类之中的变量与函数,所以变量通过 self.变量名 操作。
不是所有的属性或方法都需要在类的头文件中声明,有的属性或方法是类的内部或者类的实例才需要使用的,设计实现细节的属性或方法最好在类扩展中声明。类似于私有成员与函数。
#import "Employee.h"@interface Employee()@property (nonatomic) unsigned int officeAlarmCode;@end@implementation Employee...
类扩展以 @interface 开始,@end 结束。类名后面加 ()。这样的改动会让变量成为私有成员。
Employee 持有一个 Asset* 类型的 holder 指针标识持有关系,每一个 Asset 中也存在一个 Employee* 类型的 holder 指针标识所属关系。
-(void)addAsset:(Asset*)a{ if(!assets) { assets = [NSMutableArray new]; } [assets addObject:a]; a.holder = self;}
以上简单处理的“相互拥有”的所属关系导致的相关对象都无法被释放,这种情况就是 强循环引用 导致的内存泄露。
弱引用是不说明所有权的指针,不增加引用计数。
@property (nonatomic, weak) Employee *holder; 或_weak Employee *holder;
当弱引用指向的对象被释放时,相应的指针变量会被复位 nil。
转载地址:http://gmxni.baihongyu.com/