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更像新建立起来的有良好规划性的卫星城。