NSArray

有顺序;固定的,一旦创建,里面的元素不可变;只能放OC的对象(且任何OC的对象都能放入);不能放nil(有特殊意义,代表数组结束);

创建:

NSArray *array = [NSArray array]; //创建一个空数组

[NSArray arrayWithObject:@"123"];//创建一个带1个元素的数组

[NSArray arrayWithObjects:@"123",@"345", nil];//创建一个带多个元素的数组,nil表示数组结束

方法:

[array count]:返回数组中元素个数

[array containsObject:@「123」]:判断是否包含了某个元素;

[array lastObject]:返回数组的最后一个元素;

[array objectAtIndex:1]:返回在index=1处的元素

[array indexOfObject:@「345」]:返回元素在数组中的位置

[array isEqualToArray:array]:判断两个数组里的元素是否相同

[array makeObjectsPerformSelector:@selector(length)]:让元素内所有的元素都调用一次元素的方法(这里是str的length方法);

可带参数:withObject:执行的方法可带一个参数(但最多只能带一个参数);

[array arrayByAddingObject:@「3」]:添加一个元素,返回一个新数组,原数组array不变;

[array arrayByAddingObjectsFromArray:array2]:将两个数组合并,返回一个新的数组,原数组都不变;

array3 subarrayWithRange:NSMakeRange(1, 2):截取指定范围和长度的元素,返回一个新的数组

[array componentsJoinedByString:@「,」]:用指定的分隔符拼接所有的元素,返回一个拼接后的字元串

[array writeToFile:@"/Users/sionfan/work/aaa.xml" atomically:YES];//将数组写入到文件中;

[NSArray arrayWithContentsOfFile:path]://从文件中读取一个数组,但文件中的格式必须是和生成的的格式一样的xml

— 排序 -

[array sortedArrayUsingSelector:@selector(compare:)]:返回一个排好序的新数组,原数组的内容顺序都不会改变;会使用对象的指定的方法进行排序;(同java,需要在对象的类中实现一个比较方法,如-(NSComparisonResult)compareStudent:(Student *)stu;);

利用block排序sortedArrayUsingComparator,(同java)需要修改自动生成的方法的形参名:

//利用block进行排序

NSArray *stus3 = [stus sortedArrayUsingComparator:^NSComparisonResult(Student *obj1, Student *obj2) {

//先按姓排序

NSComparisonResult result = [obj1.lastName compare:obj2.lastName];

if (result == NSOrderedSame) {

//姓相同

result = [obj1.fistName compare:obj2.fistName];

}

return result;

}];

— 多条件排序 sortedArrayUsingDescriptors:desces—

//先按书名排序,对应上student类中book.bookName的名字;

NSSortDescriptor *bookDesc = [NSSortDescriptor sortDescriptorWithKey:@"book.bookName" ascending:YES];

//再按姓进行排序

NSSortDescriptor *lastDesc = [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES];

//再按名进行排序

NSSortDescriptor *firstDesc = [NSSortDescriptor sortDescriptorWithKey:@"firstName" ascending:YES];

//顺序添加排序描述器到数组

NSArray *desces = [NSArray arrayWithObjects:bookDesc,lastDesc,firstDesc, nil];

NSArray *stus5 = [stus sortedArrayUsingDescriptors:desces];

@[@「,@「」」];可直接创建一个数组,但是不可变数组(NSArray)

++ 遍历(4种方式) +

for(int i;i<count;i++){id obj = [array objectAtIndex:i]};

for(id *str in array){..str..};//快速遍历

[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

//id obj:遍历到的对象

//idx :遍历到的位置

//stop:是否要中止遍历;*stop = YES;//加*才能改变外面的bool值

NSLog(@"%@,%i",obj,idx);

}];

迭代器遍历

//迭代器遍历,先产生一个迭代器

//正向迭代器

// NSEnumerator *enumerator = [array objectEnumerator];

//返序迭代器,从末尾迭代

NSEnumerator *enumerator = [array reverseObjectEnumerator];

//获取下一个需要遍历的元素

id obj = nil;

while(obj = [enumerator nextObject]){

NSLog(@"%@",obj);

};

//返回迭代器中所有元素组的一个数组,只取出没有遍历过的对象,所有在while遍历后为空

NSArray *array2 = [enumerator allObjects];

++ NSMutableArray ++继承自NSArray,可变数组

实现所有NSArray的方法;

增加add***,insert**,replace**及remove**方法;[调用一次add**方法会调用元素retain操作,计数器值+1;调用一次remove**方法会调用元素的release操作,计数器值-1;以此保证不会内存泄露]

[排序:由于可变,可直接对本数组进行排序,故对应的方法多了三个没有_ed的排序方法,可直接对原数组进行排序]

只能添加不为nil的OC对象

** 内存管理 **

当把一个对象塞进一个数组中时,这个对象的计数器会加1;

//当数组被销毁时,会对内部的所有元素都做一次release操作;

[array release];

+ NSSet (同java中的set,不常用)

++ NSDictionary ++字典,通过惟一的key找到对应的value(类似于java中的map)

NSDictionary是不可变的;一旦创建就不可再更改;不能放基本数据和nil;只能放OC对象;(key唯一)

— 创建 —

[NSDictionary dictionary]:

[NSDictionary dictionaryWithObject:@"v" forKey:@「key」];

[NSDictionary dictionaryWithObjectsAndKeys:@"v2",@"k1",@"v3",@"k2", nil];

[NSDictionary dictionaryWithContentsOfFile:path]:从一个文件读取并生成一个map;但必须先是生成格式的xml

[NSDictionary dictionaryWithObjects:objects forKeys:keys];

— 方法 —

[dict count]:有几个键值对;

[dict objectForKey:@「k1」]:通过key找value;但只能取,不能改;

[dict writeToFile:@"/Users/sionfan/work/ddd.txt" atomically:YES]; //将字典写入到一个文件中,也是生成一个xml文件;

[dict allKeys]:所有的key的NSArray(无顺序)

[dict allValues]:所有的value的NSArray(无顺序)

[dict3 objectsForKeys:[NSArray arrayWithObjects:@"k1",@"k2",@"k3", nil] notFoundMarker:@「notfound」];//用一组keys找一组values;notFoundMarker是没有的找到时的返回值,不能为nil;

[dict keysSorted***:]对keys进行排序;相当于对keys这个NSArray进行排序,方法也类似;

—遍历—

//1.循环遍历

for(id key in dict3){

NSLog(@"%@ = %@",key,[dict3 objectForKey:key]);

}

//2.迭代器遍历 key迭代器

NSEnumerator *keyEnumerator = [dict3 keyEnumerator];

//value迭代器

// NSEnumerator *valueEnumerator = [dict3 objectEnumerator];

id key = nil;

while (key = [keyEnumerator nextObject]) {

NSLog(@"%@ = %@",key,[dict3 objectForKey:key]);

}

//3.block迭代器遍历

[dict3 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {

//*stop=YES,停止遍历

NSLog(@"block %@ = %@",key,obj);

}];

— NSDictionary内存管理—同NSArray;在创建时对象引用+1;在调用remove**方法时会对remove的对象调用一次release操作;当dict销毁时也会对里面所有的key和value执行一次release操作(计数器值-1);

++NSMutableDictionary++是NSDictionary的子类

增加修改类的方法

set***;add***;remove***;replace***

[void * 代表任何指针]

[在对json数据解析时,若数据的值为null或为空;则不会创建这个键值对]

++ NSValue ++

用于包装结构体,也能包装任意类型(包装基本类型)。

包装:valueWith**:

解包:**Value:

对于自定义的结构体:

Date date = {1999,9,12};

char *type = @encode(Date);//根据结构体类型生成对应的类型描述字元串

NSValue *dateValue = [NSValue value:&date withObjCType:type];

//取出时,先定义一个结构体

Date d2 ;

//取出放入的值

[dateValue getValue:&d2];

//取出放入的objcType

[dateValue objCType];

++ NSNumber ++继承自NSValue

由于字典和数组不能放入基本数据,故需要转换;这里可用NSNumber来包装。但不像java那样自动打包解包;放入什么,取出来就是什么;(但只能包装基本数据,不能包装结构体)

初始化:

numberWith**(基本类型:)

还原成基本类型:init**;

++ NSNull ++

由于集合中不能放空(nil);为了达到能放入一个空值,就使用NSNull。是一个OC对象。

创建:只有一个方法 [NSNull null]:

是单例的(所有的对象指向的都是同一块地址)

++ NSDate ++时间相关

//NSData,是一个位元组数组(类似于Java中的byte[]);

//NSDate才是时间

NSDate *date = [NSDate date];//返回当前时间

NSLog(@"%@",date);

//单位是秒,IOS中的时间都是以秒为单位

date = [NSDate dateWithTimeIntervalSinceNow:10];//以当前时间+10

NSLog(@"%@",date);

date = [NSDate dateWithTimeIntervalSince1970:100];//以70-1-1年的时间开始增加,将long型毫秒值转成Date

NSLog(@"%@",date);

date = [NSDate distantFuture];//随机的返回一个将来的时间

date = [NSDate distantPast];//随机的返回一个过去的时间

NSTimeInterval interval = [date timeIntervalSinceReferenceDate];//返回毫秒数long

// [date timeIntervalSince1970];//返回当前时间的毫秒值

// [date isEqualToDate:[NSDate date]];//比较两个时间是否相同

// [date earlierDate:date1];//返回比较早的那个时间

// [date laterDate:date1];//返回比较晚的那个时间

//时间格式化

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"yyyy-MM-dd hh:mm:ss";

NSString *time = [formatter stringFromDate:date];//将日期转换成string

time = @"2016-02-03 10:23:30";

date = [formatter dateFromString:time];//将string转换成日期

NSCalendar *calender = [NSCalendar currentCalendar];//类似于Java中 Calender

++ NSObject ++与反射

id stu = [Student new];

//isKindOfClass 判断对象是否属于某个类 或者 子类

if ([stu isKindOfClass:[Student class]]) {

NSLog(@"属于这个类");

}

//isMemberOfClass 判断对象是否属于某个类(但不包括子类)

if([stu isMemberOfClass:[Student class]]){

NSLog(@"属于这个类");

}

//间接调用对象的方法,还要带其他参数

// [stu performSelector:@selector(test)];

//延迟调用,在IOS中才有用,main是循环的,才能执行,在命令行的项目中,main只有一次,不能延迟

// [stu performSelector:<#(nonnull SEL)#> withObject:<#(nullable id)#> afterDelay:<#(NSTimeInterval)#>]

//其他线程调用对象的方法

// [stu performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]

++ 反射 ++

//反射,通过字元串生成一个对象

NSString *str = @"Student";

Class class = NSClassFromString(str);

//类的反射

Student *stu = [[class alloc] init];

//Class 变成字元串

// NSString *name = NSStringFromClass([Student class]);

NSLog(@"%@",stu);

//方法的反射

NSString *method = @"test";

//得到方法

SEL selector = NSSelectorFromString(method);

//执行方法

[stu performSelector:selector];

//将SEL转化为字元串

NSString *selectorName = NSStringFromSelector(selector);

++ copy ++

目的:就是对一个对象和集合的拷贝,改变副本不影响原对象(同java中的clone)。

*创建不可变副本(copy):要先实现NSCopying协议,创建的是不可变副本(NSString,NSArray);

*创建可变副本(mutableCopy),要实现NSMutableCopying协议,用于创建可变副本(NSMutableString,NSMutableArray);

深拷贝(mutableCopy,内容拷贝):是会产生一个新的对象,是真正的拷贝,从内存中拷贝出一份,并指向它。新对象的计数器值为1,原对象的计数器值不变。

浅拷贝(copy):只是简单的指针拷贝(地址拷贝)。如对于如NSString的对象,由于这类对象本身不可改变,为了性能提升,故copy方法不会创建一个新的对象,是将原对象本身返回,且原对象的计数器+1(相当于retain操作)

[两者区别是有没有产生新对象;但还有特殊情况,是NSMutableString str=..;NSString *str2 = [str copy];

//可变对象 ——> 不可变对象 和 不可变对象 ——> 可变对象,由于拷贝出的对象与原对象的结构都不一样,所以不能简单的指针拷贝,故是深拷贝。(只有一种情况:不可变—copy—>不可变才是浅拷贝)]

在定义对象时用copy: @property (nonatomic,copy) NSString *lastName;//修改外面的变数,不会影响到内部的成员变数(对于固定的NSString一般用copy,不允许随便修改)

则代表在set方法中,会release旧对象,copy新对象:[_lastName release];_lastName = [lastName copy];

在外面用操作mutable时,就不会改变对象中的值:NSMutableString *string = …; stu.lastName = string;//赋值; [string appendString@「..」];//改变赋值的字元串,则不会改变对象中的字元串的值。(用retain,则对象中的值会改变)

使用copy时,建议使用[self class]代替类名;

[子类继承父类,在构造方法时,实例化使用Student *stu = [[[self class] alloc] init];//让子类来调用父类的方法,不然父类可能调用到子类的方法,出现找不到方法的错误]


推荐阅读:
相关文章