iOS开发基础(一)

iOS的应用程序是运行在沙盒中的,也就是说各个应用无法访问除自己外的其它应用的地址。
接下来,我将对iOS开发中常用的组件NSButton,NSImage,NSLabel做一个总结。
Xcode提供了Interface Builder来方便快速地创建应用界面。

我们可以将想要的控件从这里拖到view上,完成添加。
通过Outlet插座,按住Ctrl+控件拖拽到对应的ViewController的.h文件中可以将IB中的组件添加到代码里,方便代码的操作。包括添加属性(IBOutlet)和相应方法(IBAction)。

通过代码添加控件

把控件加入页面view[self.view addSubview:(UIView)]
1 这个方法会retain一次view,并且设置它的下一个响应者是receiver,即它的新的父视图。
2 每一个视图只能有唯一的一个父视图。如果当前操作视图已经有另外的一个父视图,则addsubview的操作会把它先从上一个父视图中移除(包括响应者链),再加到新的父视图上面。

UILabel

1   建立UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(x, y, width, height)]; 
2   
3   常用属性 //设置显示文字     
4   label.text = @"label1";
5   //设置字体:粗体,正常的是 SystemFontOfSize     
6   label.font = [UIFont boldSystemFontOfSize:20];     
7   //设置文字颜色  
8   label.textColor = [UIColor orangeColor];   
9   //设置文字排版方式     
10  label.textAlignment = UITextAlignmentRight;     
11  label.textAlignment = UITextAlignmentCenter;     
12  //设置字体大小适应label宽度     
13  label.adjustsFontSizeToFitWidth = YES;
14  //设置label的显示行数  
15  label.numberOfLines = 2; 
16  //背景色,也可以设置背景图   
17  label.backgroundColor=[UIColor clearColor]; //可以去掉背景色   
18  //设置高亮     
19  label.highlighted = YES;     
20  label.highlightedTextColor = [UIColor orangeColor];     
21  //设置阴影     
22  label.shadowColor = [UIColor redColor];     
23  label.shadowOffset = CGSizeMake(1.0,1.0);     
24  //设置是否能与用户进行交互     
25  label.userInteractionEnabled = YES;     
26  //设置label中的文字是否可变,默认值是YES     
27  label.enabled = NO;     
28  //设置文字过长时的显示格式     
29  label.lineBreakMode = UILineBreakModeMiddleTruncation;//截去中间     
30  //  typedef enum {     
31  //      UILineBreakModeWordWrap = 0,     
32  //      UILineBreakModeCharacterWrap,     
33  //      UILineBreakModeClip,//截去多余部分     
34  //      UILineBreakModeHeadTruncation,//截去头部     
35  //      UILineBreakModeTailTruncation,//截去尾部     
36  //      UILineBreakModeMiddleTruncation,//截去中间     
37  //  } UILineBreakMode;     
38  

UIButton

1   建立 //UIButton的定义
2   UIButton *button=[[UIButton buttonWithType:(UIButtonType);
3   //typedef enum {
4   //  UIButtonTypeCustom = 0, 自定义风格
5   //  UIButtonTypeRoundedRect, 圆角矩形
6   //  UIButtonTypeDetailDisclosure, 蓝色小箭头按钮,主要做详细说明用
7   //  UIButtonTypeInfoLight, 亮色感叹号
8   //  UIButtonTypeInfoDark, 暗色感叹号
9   //  UIButtonTypeContactAdd, 十字加号按钮
10  //} UIButtonType;
11  
12  常用方法//设置frame
13  button.frame = CGRectMake(20, 20, 280, 40);
14  [button setFrame:CGRectMake(20,20,50,50)];
15  
16  //button背景色
17  button.backgroundColor = [UIColor clearColor];
18  [button setBackgroundColor:[UIColor blueColor]];
19  
20  //是否可点击,默认为YES
21  button.enable = NO;                          
22  //设置button填充图片和背景图片
23  [button setImage:(UIImage) forState:UIControlStateNormal];
24  [button setBackgroundImage:(UIImage)forState:UIControlStateNormal];
25  //设置button标题和标题颜色
26  [button1 setTitle:@"点击" forState:UIControlStateNormal];
27  [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
28  
29  //添加或删除事件处理
30  [button addTarget:self action:@selector(butClick:)forControlEvents:UIControlEventTouchUpInside];
31  [button removeTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];
32  

UIImageView

1   建立UIImageView *imageView = [[UIImageView alloc ] init];
2   //UIImage加载有两种方式
3   //方案1
4   UIImage *image = [UIImage imageNamed:@"image_photo"];
5   //方案2
6   NSString *filePath=[[NSBundle mainBundle] pathForResource:@"image_photo" ofType:@"jpg"];
7   UIImage *image=[UIImage imageWithContentsOfFile:filePath];
8   
9   imageView.image = image;
10  


方案一:用imageNamed的方式加载时,系统会把图像Cache到内存。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的内存是一件相对来说比较麻烦的事情。例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一个UIView的对象的animationImages进行逐帧动画,那么这将会很有可能造成内存泄露。并且释放图像所占据的内存也不会那么简单。但是利用imageNamed加载图像也有自己的优势。对于同一个图像系统只会把它Cache到内存一次,这对于图像的重复利用是非常有优势的。例如:你需要在一个TableView里重复加载同样一个图标,那么用imageNamed加载图像,系统会把那个图标Cache到内存,在Table里每次利用那个图像的时候,只会把图片指针指向同一块内存。这种情况使用imageNamed加载图像就会变得非常有效。方案二:就是每次单独加载图片,系统不缓存。使用完后记得释放。

1   常用方法 //设置圆角
2   imageView.layer.masksToBounds = YES;
3   imageView.layer.cornerRadius = 10;
4   
5   //设置边框颜色和大小
6   imageView.layer.borderColor = [UIColor orangeColor].CGColor;
7   imageView.layer.borderWidth = 2;
8   
9   //播放一系列图片
10  UIImage *image1 = [UIImage imageNamed:@"1"];
11  UIImage *image2 = [UIImage imageNamed:@"2"];
12  UIImage *image3 = [UIImage imageNamed:@"3"];
13  NSArray *imagesArray = @[image1,image2,image3];
14  imageView.animationImages = imagesArray;
15  // 设定所有的图片在多少秒内播放完毕
16  imageView.animationDuration = [imagesArray count];
17  // 重复播放多少遍,0表示无数遍
18  imageView.animationRepeatCount = 0;
19  // 开始播放
20  [imageView startAnimating];
21  
22   //为图片添加单击事件:一定要先将userInteractionEnabled置为YES,这样才能响应单击事件
23  imageView.userInteractionEnabled = YES;
24  UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView:)];
25  [imageView addGestureRecognizer:singleTap];
26  
27  //其他设置
28  imageView.hidden = YES或者NO;    // 隐藏或者显示图片
29  imageView.alpha =0.5;    // 设置透明度
30  // 设置高亮时显示的图片
31  imageView.highlightedImage = (UIImage *)hightlightedImage;
32  imageView.image = (UIImage *)image; // 设置正常显示的图片

UITextField

1   建立UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(x, y, width, height)];
2   
3   常用方法textField setBorderStyle:UITextBorderStyleRoundedRect]; //外框类型
4   textField.placeholder = @"password"; //默认显示的字 
5   textField.secureTextEntry = YES; //密码 
6   
7   textField.autocorrectionType = UITextAutocorrectionType; //设置是否自动纠错
8   typedef enum {
9       UITextAutocorrectionTypeDefault, //默认
10      UITextAutocorrectionTypeNo,  //不自动纠错
11      UITextAutocorrectionTypeYes, //自动纠错
12  }UITextAutocorrectionType;
13  
14  textField.clearButtonMode = UITextFieldViewMode; //编辑时会出现个修改X
15  typedef enum {
16      UITextFieldViewModeNever, //重不出现
17      UITextFieldViewModeWhileEditing, //编辑时出现
18      UITextFieldViewModeUnlessEditing, //除了编辑外都出现
19      UITextFieldViewModeAlways  //一直出现
20  }UITextFieldViewMode; 
21  
22  //可以在UITextField使用下面方法,按return键返回
23  -(IBAction) textFieldDone:(id) sender
24  {
25   [textFieldName resignFirstResponder]; 
26  }
27  //链接TextField控件的"Did end on exit"
28  
29  //再次编辑就清空
30  textField.clearsOnBeginEditing = YES; 
31  
32  //设置键盘样式
33  textField.keyboardType = UIKeyboardType;
34  typedef enum {
35          UIKeyboardTypeDefault,      //默认键盘,支持所有字符         
36          UIKeyboardTypeASCIICapable, //支持ASCII的默认键盘
37          UIKeyboardTypeNumbersAndPunctuation, //标准电话键盘,支持+*#字符
38          UIKeyboardTypeURL,            //URL键盘,支持.com按钮 只支持URL字符
39          UIKeyboardTypeNumberPad,       //数字键盘
40          UIKeyboardTypePhonePad,   //电话键盘
41          UIKeyboardTypeNamePhonePad,  //电话键盘,也支持输入人名
42          UIKeyboardTypeEmailAddress,  //用于输入电子邮件地址的键盘     
43          UIKeyboardTypeDecimalPad,    //数字键盘有数字和小数点
44          UIKeyboardTypeTwitter,       //优化的键盘,方便输入@、#字符
45          UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable, 
46  }UIKeyboardType;
47  
48  //return键样式
49  text.returnKeyType =UIReturnKeyType;
50  typedef enum {
51      UIReturnKeyDefault, 默认 灰色按钮,标有Return
52      UIReturnKeyGo,     标有Go的蓝色按钮
53      UIReturnKeyGoogle,标有Google的蓝色按钮,用语搜索
54      UIReturnKeyJoin,标有Join的蓝色按钮
55      UIReturnKeyNext,标有Next的蓝色按钮
56      UIReturnKeyRoute,标有Route的蓝色按钮
57      UIReturnKeySearch,标有Search的蓝色按钮
58      UIReturnKeySend,标有Send的蓝色按钮
59      UIReturnKeyYahoo,标有Yahoo的蓝色按钮
60      UIReturnKeyYahoo,标有Yahoo的蓝色按钮
61      UIReturnKeyEmergencyCall, 紧急呼叫按钮
62  } UIReturnKeyType;
2016/5/30 1:43 上午

Objective-C复习笔记(二)

ARC机制

以往的OBJC是通过程序员手动地管理对象的释放。ARC(Automatic Reference Counting)自动引用计数,现在是OBJC的默认内存管理机制,针对堆上的对象,由编译器自动生成操作引用计数的指令(retain,release)来管理对象的释放。

管理的对象

受ARC管理 不受ARC管理
OC对象指针 值类型(基本类型,struct)
Block指针 其他方式分配的资源(c语言的malloc)
使用_attribute_((NSObject))定义的typedef 非内存资源

管理的方式

//新创建一个引用类型的对象,这个对象的引用计数初始为1;
NSString *name = [[NSString alloc] initWithString:@"Mono"];
//将对象引用赋值给其它变量或者常量,引用计数+1;
NSString *otherName = name;
//或者将将该对象引用赋值给其它对象的属性或实例变量,引用计数+1;
person.name = name;
//将对象传入函数参数,或者返回值,引用计数+1
print(name);//函数结束后,参数或者局部变量离开函数,该对象的引用计数-1;
//将对象加入集合之中,引用计数+1;
[array addObject];

//将变量或者常量,或者属性赋值为nil或者其他值,引用计数-1;
otherName = nil; or otherName = @"Other Name";
person.name = nil;
//实例变量和属性所在的对象呗释放,该对象引用计数-1;
[person release];
//将对象从集合中移除的时候,该对象的引用计数-1;
[array removeObject:name];

//当该对象的引用计数变为0的时候,内存自动被释放。

自动释放池(Autorelease Pool)

如果对象频繁的进行释放和分配,那么会造成琐碎的内存管理负担。autorelease可以讲release的调用延迟到自动释放池被释放时。

当自动释放池结束时,所有接受autorelease消息的对象都将被立即释放(对象被发送一条release消息);

AppKit和UIKit框架在处理每一次事件循环迭代时,都会讲其放入一个Autorelease Pool中,大多数情况无须程序员干预。

需要手动管理Autorelease Pool的情况

1.当编写的程序不是基于UI框架,而是命令行程序时。
2.如果在循环中创建大量临时对象,需要更早地释放,避免临时对象聚集导致内存峰值过大。
3.在主线程之外创建新的线程,在新线程开始执行处,需要创建自己的Autorelease Pool。
4.嵌套使用Autorelease Pool的时候。

协议 Protocol

类型的合同约定,只描述外部接口,不提供具体的实现。
协议中无法包含实例变量,但可以包含以下的成员:
属性 (本质上是访问器方法,编译器不会合成实例变量)
实例方法
类方法
初始化器,析构器(不常用)

使用协议

1.一个类遵守协议,需实现该协议约定的所有@required的成员,即必须要实现的成员。
协议中的属性必须在实现类的.h接口文件中声明(编译器合成实例变量)
2.协议本质上是一种类型,可以作为声明类型,但是不能创建实例。
3.可以使用conformsToProtocl:检查是否实现了协议。
4.编译警告:1)未实现必选方法。2)协议类型变量被赋值为非协议类型变量。运行会出错。

协议的继承

一个协议可以继承一个或者多个协议。
实现子协议的类型,同时也要实现父协议中必须是实现的成员。

协议的组合

一个类可以同时实现多个协议,protocal来组合多个协议
实现组合协议的类型,必须实现组合协议中的每一个协议

协议中的可选

协议中使用关键字@optional定义的成员是可以选择不必实现的。

常用的协议

名称 描述
NSObject 包含对象的常用操作,相等、字符串表示、哈希。
NSCopying 支持复制的类型必须遵守该协议。
NSMutableCopying 在NSCopying协议的基础上,支持复制数据的可变性。
NSFastEnumeration 实现快速枚举for-in的类型采用
NSCoding 支持将对象图进行编码或解码以支持对象的序列化

类别 Categroy

在没有源代码的情况下,基于某些场合的需要,为一个类增加功能。
可增加 | 不可增加
--------- | -------------
类方法 | 属性
实例方法| 实例变量
重写父类方法 | 已存在的同名方法

命名规范

文件名:类名+扩展方法,如:Person+Sport.h/m

类别的使用

场景

1.适合在没有源代码的情况下,想已经封装的类中添加方法。
2.为一个类在某些特殊场景下增加功能。
3.对于复杂的大型文件分割实现。
4.可以通过类别重写现有方法,但一般不推荐,这样会导致无法调用被扩展的类的初始方法,只能访问重写过的方法。

添加类别的对象

1.自己创建的类。
2.系统的类。
3.第三方库。

类别限制

1.类别不能在扩展类中添加任何成员变量。
2.重写现有方法时,无法调用原始现有对象方法。
3.若两个类别都定义了一个相同类的相同方法,运行时实际无法确定调用哪一个。

扩展 Extension

扩展支持在编译时,在有类的源代码的前提下,向类添加功能。可看做是匿名的类别。

接口在.m文件中的@implementation前声明,实现代码在@implementation 内实现。

扩展支持添加以下成员:
1.属性。
2.实例成员。
3.类方法。
4.实例方法。
5.改写属性的读写属性。

扩展的使用

扩展实现的成员只能在。m文件内部访问,类外无法直接往访问。

扩展的主要用途在于信息隐藏,隐藏一些外部无须访问、而内部实现又需要使用的属性、方法:
1.类的主要接口用于“对类以外公开”
2.类的扩展接口用于“对类内可见”

2016/5/20 10:46 上午

Objective-C复习笔记

Objective-C简介

Objective-C简称Objc或者OC,是一种基于C语言的面向对象程序设计语言。1980年代产生,主要在苹果电脑平台上使用,开发Cocoa或Cocoa Touch应用程序。
通过LLVM编译器架构,可以苹果家最新的编程语言Swift进行双向操作。不过终有一天将会被Swift取代。

开发方式

命令行

clang -fobj-arc *.m
-fobj-arc表示支持ARC内存管理
适合研究、调试、学习

IDE

通过Xcode构建正规工程项目
有利于构建高质量的代码组织

类与对象

在OC中所有的类都是引用类型,所有c语言中的基本数值类型都是值类型。此外,详细的类型说明如下表所示:

引用类型(reference) 值类型(value type) 类型装饰
类 class 基础数值类型 协议 protocol
指针 pointer 结构 struct 类别 category
快 block 枚举 enum 扩展 extension

类与结构体的区别

类 class 结构 struct
实例 对象
类型 引用类型(栈:指针,堆:实体对象) 实例直接存在在栈中

栈和堆的区别

栈 stack 堆 heap
存储类容 值类型 引用类型的对象
管理方式 由系统自动管理,函数为单位 分配由程序员手动请求
具体 空间大小编译时确定(参数+全局变量) 释放由运行时ARC机制自动释放(确定是)
具体 函数执行时,系统自动分配stack
具体 函数结束后,系统立即自动回收stack
传递方式 函数间直接通过拷贝值传递 函数间通过拷贝引用(指针)传递
限制 有局部性,大小有限额,超出stack overflow 有全局性,无大小限制(受制系统内存大小)

属性与实例变量

数据成员描述对象的状态:1.实例变量instance variable。2.属性property。

属性

属性描述的是对象的状态,是对外的接口(相当于是public)。
声明一个属性的同时,编译器会自动为这个属性生成:
1.getter访问器方法: properyName
2.setter访问器方法: setProperyName
3.一个对应的实例变量: _propery

访问器方法可以自定义。访问器方法名也可以修改。对应的实例变量名也可以修改。但是一般使用编译器默认生成的,以便统一规范。

使用静态全局变量(c语言)+类方法,可以模拟类属性。

实例变量

可在不声明属性的情况下定义实例变量。只有实例变量,无类变量。
若单独自定义了访问器方法,则编译器就不在合成实例变量。
类外使用属性来访问,类内一般也是用属性访问即self.
以下情况例外:
初始化器 init
析构器 dealloc
自定义访问器方法中

生存周期
实例变量存储在堆上。
值类型实例变量内嵌在对象实例中,随着对象实例释放。
引用类型的实例变量通过指针引用堆上的实例,ARC对引用进行计数管理,自动施放。

属性的描述特性
Attribute可指定属性的不同功能。

读写: readwrite(默认),readonly
多线程: atomic(默认), nonatomic

内存管理特性
ARC下:
strong(默认), weak(阻止循环引用), copy(创建独立拷贝)
MRC下:
retain
assign
unsafe_unretained

方法

函数成员描述对象的行为:1.方法method。2.初始化器init。3.析构器dealloc。

函数指的是代码段上可执行指令序列,OC中称为方法。
所有的方法默认都是公有的,没有private和protected。
方法调用通过运行时动态消息分发实现,OC中称为向对象发送消息。

方法的类型

实例方法,可访问:
实例成员。
类型方法、静态变量。

类方法
可访问:类型方法、静态变量
无法访问实例成员。

方法的参数

参数为值类型,则为值传递方式;为引用类型,则为指针传递;
方法可以无参数和返回值。

初始化器和析构器

初始化器用于初始化对象实例或类型:
对象初始化:-(id) init 可以重载多个
alloc:1.在堆上分配合适大小内存。2.将属性或实例变量的内存置0。
init:1.调用父类初始化器[super init]。2.初始化当前对象实例变量。
new相当于alloc/init的无参数版本。
类型初始化:+(void) initialize 只能一个
负责类型级别初始化。
每个类使用前被系统自动调用,每个进程周期只调用一次。
子类调用父类的initialize方法。

析构器用于释放对象的资源,无返回值。
只能一个。
无类型析构器。

自动:ARC将对象属性引用计数减持。
手动:1.释放不受ARC管理的动态内存,如malloc。
2.关闭非内存资源,如文件句柄,网络资源。

dealloc由ARC自动在释放对象内存前调用,无法手工调用。
子类dealloc会自动调用父类的dealloc(后置调用)。

继承与多态

继承的含义:
成员复用:子类复用父类成员
类型抽象:将子类当做父类使用(IS-A关系准则)

多态:
子类在父类统一行为接口下,表现不同的实现方式。

OC不支持重载,子类只能重写与父类同名同参数方法。

子类中通过super调用父类实现。
self具有多态性,可以指向不同的子类。
super无多态性,仅指向当前父类。

init和dealloc的继承

init:
子类自动继承父类的初始化器。
子类也可以重写父类的初始化器,此时子类初始化器必须先调用父类的一个初始化器。

dealloc:
子类可以选择继承父类析构器或者重写父类析构器。
子类析构器执行完后会自动调用父类的析构器(后置调用,且不支持手工调用)。
子类析构器自动具有多态性。

2016/5/14 22:33 下午 posted in  Objective C