IOS 学习笔记(第二次冲击 Objective-C部分)PART 2
终于再次迈入Objective-C的部分了,之前迈入的那次完全没有进入状态,我在嘟囔它这不好那不好的同时,慢慢开始认可了它是怪咖的事实,并开始认为征服一个怪咖是一件很有成就感的事(何况它是个能make money的怪咖),所以决定把它当成邻桌的怪同学来和平相处。
Primitive Types
基本数据类型和对应的占位以及长度表述如下图:
[caption id=”” align=”aligncenter” width=”913”] Primitive Data Type Ranges[/caption]
然后是它奇葩的方法定义公式:
-(returnType)methodNameParam1Name:(param1Type)param1RefName param2Name:(param2Type)param2RefName{ }
于是我用这个公式定义了一对儿getter和setter
#import <Foundation/Foundation.h> @interface Shape : NSObject { float _area; } -(float)area; -(void)setArea:(float)area; @end
并在.m文件中实现了它们
#import "Shape.h" @implementation Shape -(float)area{ return _area; } -(void)setArea:(float)area{ _area = area; } @end
Property
如果不需要对定义的值做复合操作,可以用直接定义属性的方式,代替上面的代码,如下。
@property(nonatomic,assign)int type;
解释nonatomic,atomic,assign,strong,weak这些关键词的文章,笔记,在Google上百花齐放,各说各话,我很困惑,这个问题先挂起,待日后详细了解在做记录。
方法调用:
[varName methodName:params];
数组 NSArray
NSArray *arr = [[NSArray alloc] initWithObjects:@1,@“abc”, nil];
长度可变更的数组 NSMutableArray,
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:arr]; [mutableArray addObject:@"def”];//添加新对象 [mutableArray objectAtIndex:0];//获取对应下标的对象 [mutableArray removeObjectAtIndex:0];//删除对应下标的对象
键值表 NSDictionary
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"Transpotting",@"title", nil]; NSLog(@"The Book is %@",[dic objectForKey:@"title"]);
容量可变的键值表 NSMutableDictionary
NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] initWithDictionary:dic]; [mutableDic setObject:@"Irvine.Welsh" forKey:@"author"]; NSLog(@"The book' author is %@",[mutableDic objectForKey:@"author"]);
ShortHand for Literal
简写的语法使得上面那看不出个数的定义们略微清晰了一些,以下写法可以代替上面的各种初始化赋值写法。
NSNumber *number = @100.0; NSString *google = @"http://www.google.com"; NSArray *newArr = @[@"yes",@"it”,@“is”]; NSDictionary *newDic = @{ @"title":@"Transpotting",@"author":@"Irvine.Welsh"}; NSLog(@"The book' author is %@",[newDic objectForKey:@"author"]);
Pointer再探
因为要操作对应内存地址的值,单纯的操作对应的值,并给予赋值会造成内存的重复占用(嗯,目前理解的是这样)
随着这个路线,我决定好好折腾一下这里,首先定义一个整数类型的变量,并赋值为100,并创建一个自增的函数:
void increase(int *i); int main() { @autoreleasepool { int i = 100; int *pi = &i; NSLog(@"int i address %p",pi); increase(pi); NSLog(@"int i value %d",i); } return 0; } void increase(int *i){ NSLog(@"pass in v address = %p",i); *i = *i + 1; }
输出结果:
int i address 0x7fff5fbff8d0 pass in v address = 0x7fff5fbff8d0 int i value 101
输出的结果证明,传入的指针与外部的指针地址相同,对应指针地址的值确实被改变了。
下面我定义了一个字符串,并输出了它的内存地址和值。
NSString *str = @"abcd" ; NSLog(@"str adress %p",str); NSLog(@"str value %@",str);
这里值得注意的是,对对象类型的变量,可以根据输出的占位符类型,指定要是要访问对象的内存地址或者存储的值。
而最基本类型的变量类型,需要用&指名要输出内存地址如下:
char cInString = [str characterAtIndex:0]; NSLog(@"cInString address %p",&cInString); NSLog(@"cInString value %c",cInString);
下面,我尝试了数组的部分:
NSArray *arr = @[ @1,str]; NSLog(@"description of array %@",arr); NSLog(@"adress of object[0] %p",arr[0]); NSLog(@"value of object[0] %@",arr[0]); NSLog(@"adress of object[1] %p",arr[1]); NSLog(@"value of object[1] %@",arr[1]); NSLog(@"adress of array %p",arr);
这里验证了,作为初始参数传入的之前的str对象,在数组中被取出时,对应的内存地址仍然相同,说明他们完全是同一个引用。不过,在我进行下面的操作时,发现了一个问题:
char cStringInArr = [stringInArr characterAtIndex:0]; char cStringInArr2 = [stringInArr characterAtIndex:0]; NSLog(@"cStringInArr value %c",cStringInArr); NSLog(@"cStringInArr adress %p",&cStringInArr); NSLog(@"cStringInArr2 adress %p",&cStringInArr2);
在多次利用字符串的characterAtIndex方法取出同样位置的char时,它们的内存地址是不同的,这个也容易理解,因为characterAtIndex返回的是unichar,并非对应的指针,所以这个行为相当于在内存开辟了新地址并存放了一个以characterAtIndex取出的值,同时将引用指向它。这段折腾还是等待C大牛来指正,比如说白爷。
还是那个感觉,这里面混杂着许多不同的规范,各个规范之间为了避免冲突都快把各种符号标记给用绝了,和AS相比较,ObjC好像当了十一朝国都的北京城,AS更像新建立起来的有良好规划性的卫星城。