Cocoa框架是iOS应用程序的基础,了解Cocoa框架,对开发iOS应用有很大的帮助。如果已经学会了如何查看文档的朋友,可以跳出这篇文章了····
Cocoa是OS X和 iOS操作系统的程序的运行环境。
是什么因素使一个程序成为Cocoa程序呢?不是编程语言,因为在Cocoa开发中你可以使用各种语言;也不是开发工具,你可以在命令行上就可以创建Cocoa程序。Cocoa程序可以这么说,它是由一些对象组成,而这些对象的类最后都是继承于它们的根类 :NSObject。而且它们都是基于Objective-C运行环境的。
iOS中,Cocoa众多框架中最重要最基本的两个框架是:Foundation 和 UIKit。
Foundation 和界面无关,也可以说和界面无关的类基本是Foundation框架的,和界面相关的是UIKit框架。
这两个框架在系统中处于的位置如图:
好吧,那我们看看两个框架的类组织架构图,第一个先看Foundation的,三个图,包括了Foundation所以的类,图中灰色的是iOS不支持的,灰色部分是OS X系统的。
将上图Foundation框架中的类进行逻辑分类如下:
值对象
集合
操作系统服务 包括下面三个:文件系统和URL 进程间通讯。这个范畴中的大部分类代表不同的系统端口、套接字、和名字服务器,对实现底层的IPC很有用。NSPipe代表一个BSD管道,即一种进程间的单向通讯通道。线程和子任务。NSThread类使您可以创建多线程的程序,而各种锁(lock)类则为彼此竞争的线程在访问进程资源时提供各种控制机制。通过NSTask,您的程序可以分出 一个子进程来执行其它工作或进行进度监控。
通知
归档和序列化
表达式和条件判断
Objective-C语言服务
应用程序可以通过三种方式使用UIKit创建界面
在用户界面工具(interface Buidler)从对象库里 拖拽窗口,视图或者其他的对象使用。
用代码创建
通过继承UIView类或间接继承UIView类实现自定义用户界面
注:UIScrollView中还有一个UICollcetionView这个子类。
框架类组织架构图:
在图中可以看出,responder 类是图中最大分支的根类,UIResponder为处理响应事件和响应链 定义了界面和默认行为。当用户用手指滚动列表或者在虚拟键盘上输入时,UIKit就生成时间传送给UIResponder响应链,直到链中有对象处理这个事件。相应的核心对象,比如:UIApplication ,UIWindow,UIView都直接或间接的从UIResponder继承。
Objective-C和Java C++一样,有封装,继承,多态,重用。但是它不像C++那样有重载操作法、模版和多继承,也没有Java的垃圾回收机制。
Objective-C语言有C++ Java等面向对象的特点,那是远远不能体现它的优点的。Objective-C的优点是它是动态的。动态能力有三种:
动态类-运行时确定类的对象
动态绑定-运行时确定要调用的方法
动态加载--运行时为程序加载新的模块
每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针。这个指针指向哪呢?它指向一个类对象(class object 记住它是个对象,是占用内存空间的一个变量,这个对象在编译的时候编译器就生成了,专门来描述某个类的定义),这个类对象包含了Objective-C对象的一些信息(为了区分两个对象,我把前面提到的对象叫Objective-C对象),包括Objective-C对象的方法调度表,实现了什么协议等等。这个包含信息就是Objective-C动态能力的根源了。
那我们看看isa指针类型的数据结构是什么样的?如果抛开NSObject对象的其他的成员数据和变量,NSObject可以看成这样:
[cpp]view plaincopy
@interface NSObject {
Class isa;
}
不考虑@interface关键字在编译时的作用,可以把NSObject更接近C语言结构表示为:
[cpp]view plaincopy
struct NSObject{
Class isa;
}
Class是用typedef 定义的
[cpp]view plaincopy
typedef struct objc_class *Class;
那NSObject可以这么写了
[cpp]view plaincopy
struct NSObject{
objc_class *isa
}
那objc_class的结构是什么样的呢?大概是这样的:
[cpp]view plaincopy
struct objc_class {
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
}
这里会看到,在这个结构体里还有一个isa指针,又是一重指向,是不是有种到了盗梦空间的感觉。不用紧张,take easy,不会有那么多层次的,这里的isa指针指向的是元类对象(metaclass object),带有元字,证明快到头了。那元对象有啥用呢?它用来存储的关于类的版本,名字,类方法等信息。所有的元类对象(metaclass object)都指向 NSObject的元类对象,到头还是NSObject。一共三次:类对象->元类对象->NSObject元类对象。
为了得到整个类组织架构的信息,objc_class结构里定义了第二个成员变量Class super_class,它指向父类的类对象。说了这么多,可能关系缕不清楚,有道是一张图胜过千言万语
图中可以看出,D3继承D2,D2继承D1,D1最终继承NSObject。下图从D3的一个对象开始,排列出D3 D2 D1 NSObject 类对象,元类对象等关系。
图中的箭头都是指针的指向。
NSObject是大部分Objective-C类的根类,它没有父类。其它类继承NSObject,访问Objective-C运行时系统的基本接口,这样其他类的实例可以获得运行时的能力。
NSObject不但是个类名,NSObject也是个协议的名称,参考NSObject协议, NSObject协议指定了根类必须实现的接口。
分配、初始化、和复制:
alloc和allocWithZone:方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。
init方法是对象初始化。
new是一个将简单的内存分配和初始化结合起来的方法。
copy和copyWithZone:
对象的保持和清理:
retain方法增加对象的保持次数。
release方法减少对象的保持次数。
autorelease方法也是减少对象的保持次数,但是以推迟的方式。
retainCount方法返回对当前的保持次数。
dealloc方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。
内省和比较
NSObjec有很多方法可以查询对象的运行时信息。这些内省方法有助于找出对象在类层次中的位置,确定对象是否实现特定的方法,以及测试对象是否遵循某种协议。下面是部分方法
superclass和class方法(实现为类和实例方法)分别以Class对象的形式返回接收者的父类和类。
您可以通过isKindOfClass:和isMemberOfClass:方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。isSubclassOfClass:类方法则用于测试类的继承性。
respondsToSelector:方法用于测试接收者是否实现由选择器参数标识的方法。instancesRespondToSelector:类方法则用于测试给定类的实例是否实现指定的方法。
conformsToProtocol:方法用于测试接收者(对象或类)是否遵循给定的协议。
isEqual:和hash方法用于对象的比较。
description方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示对象。
对象的编码和解码
下面的方法和对象的编解码(作为归档过程的一部分)有关:
encodeWithCoder:和initWithCoder:是NSCoding协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。
NSObject类中声明了一些于对象编码有关的方法:classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。
消息的转发
forwardInvocation:允许一个对象将消息转发给另一个对象。
消息的派发
在performSelector开头的一些方法允许你延迟后派发指定消息,而且可以将消息(同步或异步的消息)从辅助线程派发到主线程。
对象的四种内存管理方式,如下图所示
对象的生命周期—简化视图
保持接收到的对象
拷贝接收到的对象
自动释放池
参考:
1、http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf
2、http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html
3、http://www.cnblogs.com/csutanyu/archive/2011/12/12/Objective-C_memory_layout.html
注意:在OC中,如果对象没有强引用,就会被自动释放。那么在UI中,控件是使用weak还是strong
现总结如下:
1.从storyboard或者xib上创建控件
在控件放在view上的时候,已经形成了如下的引用关系,以UIButton为例:
UIViewController->UIView->subView->UIButton
然后你为这个UIButton声明一个weak属性
@property(nonatomic,weak) IBOOutlet UIButton *btn;
相当于xib/sb对这个Button是强引用,你声明的属性对它是弱引用。
2.手动创建控件
a). 将控件声明成strong
@property(nonatomic,strong) UIButton *btn;
那么你在实现这个控件时只需这样:
_btn = [[UIButton alloc]init];
[self.view addSubview:_btn]
b). 将控件声明成weak
@property(nonatomic,weak) UIButton *btn;
那么你在实现这个控件时需要这样:
UIButton *button = [[UIButton alloc]init];
_btn = button;
[self.view addSubview:_btn];
建议:(1)如果用Stroyboard拖线,用weak声明;(2)如果自定对象,用weak声明,其实现采用方式2;
IOS 常用UIKit 控件总结
1. UILabel
功能: 显示文本(一般是简短的)
部分属性
@property(nonatomic , copy) NSString *text; // 设置文本内容, 默认为 nil
@property(nonatomic , retain) UIFont *font; // 设置文本字体的大小
@property(nonatomic , retain) UIColor *textColor; // 设置字体颜色
@property(nonatomic , retain) UIColor *shadowColor; // 设置阴影,默认无阴影,如果需要,则同时要设置偏移量
@property(nonatomic) CGSize shadowOffset; // 设置偏移量
@property(nonatomic) NSTextAlignment textAlignment; // 文本内容对齐方式
@property(nonatomic) NSLineBreakMode lineBreakMode; // 当文本的内容超出设定的规格后,设置文本的截取方式
@property(nonatomic , retain) UIColor *highlightedTextColor; // 文本选中时, 高亮的颜色
@property(nonatomic , getter = isHighlighted) BOOL highlighted; // 是否存在高亮, 默认为 nil
@property(nonatomic , getter = isUserInteractionEnabled) BOOL userInteractionEnabled; // 交互是否打开, 默认为 NO
UILabel 实例:
UILabel *label = [[UILabel alloc ] initWithFrame: CGRectMake(50, 60, 230, 90)]; label.backgroundColor = [UIColor clearColor]; // 背景色为透明色
label.textColor = [UIColor cyanColor]; // 文本颜色
label.textAlignment = UITextAlignmentCenter; // 文本对齐方式
label.tag = 1; // 设置该实例对象的标示值
label.text = @" Happy New Year "; // 设置文本内容
label.font = [UIFont systemFontOfSize:16.0f]; // 设置文本字体
label.numberOfLines = 12; // 设置文本的行数
label.lineBreakMode = UILineBreakModeCharacterWrap; // 文本一行的内容超过预定的行宽时,对文本的打断方式
[label sizeToFit]; // 根据文本大小,自动调整 label 的宽度和高度
2.UIControl
功能:是一些具有 事件处理 的控件的父类
时间相应地3种方式:基于触摸、基于值、基于编辑。
常用方法:
-(void) addTarget:(id) target action:(SEL)action forControlEvents:(UIControlEvents) controlEvents // 添加一个事件
-(void) removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents) controlEvents // 移除一个事件
事件处理
UIControlEventTouchDown // 用户按下时触发 事件
UIControlEventTouchDownRepeat // 双击触发
UIControlEventTouchDragInside // 在控件内拖动时触发
UIControlEventTouchDragOutside // 在控件之外拖动时触发
UIControlEventTouchDragEnter // 从控件外拖动到控件里触发
UIControlEventTouchDragExit // 从控件内部拖动到控件外部
UIControlEventTouchUpInside // 触摸控件内部结束时,触发 事件
UIControlEventTouchUpOutside // 触摸控件外部结束时, 触发 事件
UIControlEventTouchCancel // 触摸取消事件
UIControlEventTouchValueChanged // 当控件的值发生改变时,用于 UISlider、UISegment
UIControlEventTouchEditingDidBegin // 文本控件开始编辑时
UIControlEventTouchEditingChanged // 文本控件中的文本被改变时
UIControlEventTouchEditingDidEnd // 文本控件结束编辑时
UIControlEventTouchEditingDidOnExit // 文本控件内通过按下回车键结束的时候
UIControlEventAllTouchEvents // 所有触摸事件
UIControlEventAllEditingEvents // 文本编辑的所有事件
UIControlEventAllEvents // 所有事件
3. UIButton
功能:用于响应用户点击事件的界面元素
部分属性
-(void) setTitle:(NSString*)title forState:(UIControlState)state; // 设置指定状态对应的标题文本
-(void) seTitleColor:(UIColor*)color forState:(UIControlState)state; // 设置指定状态对应的标题颜色
-(void) setImage:(UIImage*)image forState:(UIControlState)state; // 设置指定状态对应的显示图片
-(void) setBackgroundImage:(UIImage*)image forState:(UIControState)state; // 设置指定状态对应的背景图片
-(void) addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; // 添加按钮对应的某一个事件
UIButton的state(状态)
UIControlStateNormal // 正常
UIControlStateHighlighted // 高亮
UIControlStateDisabled // 禁用
UIControlStateSelected // 选中
UIControlStateApplication // 应用程序标志时
UIControlStateReserved // 内部框架预留时
UIButton 实例:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
/* 可以定义的 button类型有以下6种:
typedef enum{
UIButtonTypeCustom = 0, 自定义
UIButtonTypeRoundedRect, 矩形边角为圆角
UIButtonTypeDetailDisclosure,蓝色小箭头按钮, 通常作详细说明用
UIButtonTypeInfoLight, 亮色感叹号
UIButtonTypeInfoDark, 暗色感叹号
UIButtonTypeContactAdd, 十字加号按钮
} UIButtonType;
*/
button.frame = CGRectMake(10, 40, 100, 100); // 设定button 的坐标和规格
button.backgroundColor = [UIColor clearColor];
[button setTitle:@"Click" forState:UIControlStateNormal];
/* forState: 这个参数的作用是定义按钮的文字或图片,在何种状态下才会显现
有以下几种状态:
enum{
UIControlStateNormal = 0, 常规状态显现
UIControlStateHighlighted = 1 << 0 , 高亮状态显示
UIControlStateDisabled = 1 << 1 , 禁用状态才会显示
UIControlStateSelected = 1 << 2 , 选中状态
UIControlStateApplication = 0x00ff0000, 当应用程序标志时
UIControlStateReserved = 0xff000000, 为内部框架预留
};*/
/* 默认情况下, 当按钮高亮的情况下,图像的颜色会深一些, 如果下面的这个属性设为NO,则可以禁用该功能
*/
button.adjustsImageWhenHighlighted = NO;
/* 与上面的情况相同,当按钮禁用的情况下 ,,,*/
button.adjustsImageWhenDisabled = NO;
/* 设定以下属性为YES,使按钮被按下时会发光 */
button.showsTouchWhenHighlighted = YES;
/* 按下按钮,当手指离开屏幕时,触发这个事件。触发事件后,执行 buttonClick: 方法, addTarget: self 表明,这个方法在本类中也可以传入其它类的指针 */
[button addTarget: self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubView: button]; // 显示控件
4. UITextField
功能:让用户输入文字信息
部分属性
@property(nonatomic , copy) NSString *text; // 设置或获取文本内容,默认为nil
@property(nonatomic , retain) UIColor *textColor; // 设置文本内容颜色
@property(nonatomic , retain) UIFont *font; // 设置字体
@property(nonatomic) NSTextAlignment textAlignment; // 对齐样式
@property(nonatomic) UITextBorderStyle borderStyle; // 设置风格,默认无风格,需要设置
@property(nonatomic , copy) NSString *placeholder; // 提示用户输入内容文本
@property(nonatomic) BOOL clearsOnBeginEditing; // 用户编辑时,时候clear内容,默认为NO
@property(nonatomic) BOOL adjustsFontSizeToFitWidth; // 自动适应调整字体的大小,默认为NO
@property(nonatomic , assign) id delegate; // 设置代理
@property(nonatomic , retain) UIImage *background; // 设置背景,需要将textField实例的风格设置为None
@property(nonatomic , retain) UIImage *disableBackground; // 设置textField 不可用时的背景图片
@property(nonatomic , readonly , getter = isEditing) BOOL editing; // 设置是否可以编辑
@property(nonatomic) UITextFieldViewMode clearButtonMode; // 清除按钮的模式,默认不出现
@property(nonatomic , retain) UIView *leftView; // 自定义左视图
@property(nonatomic) UITextFieldViewMode leftViewMode; // 自定义左视图出现的模式
@property(readwrite , retain) UIView *inputView; // 不用系统键盘, 自定义键盘
@property(readwrite , retain) UIView *inputAccessoryView; // 系统键盘和自定义键盘共存
@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
// 自动大写类型
@property(nonatomic) UITextAutocorrectionType autocorrectionType;// 检查拼写是否正确
@property(nonatomic) UIKeyboardType keyboardType;
// 修改键盘类型
@property(nonatomic) UIReturnKeyType returnKeyType;
// 修改返回类型
@property(nonatomic , getter = isSecureTextEntry) BOOL secureTextEntry;
// 是否安全输入,比如用户输入密码
常用代理方法
// 将要开始输入时调用
-(BOOL) textFieldShouldBeginEditing:(UITextField*) textField{
NSLog(@"start inputting");
return YES;
}
// 将要输入结束是调用
-(BOOL) textFieldShouldEndEditing:(UITextField*) textField{
NSLog(@" The end of inputting");
return YES;
}
// 清除文字按钮点击事件
-(BOOL) textFieldShouldClear:(UITextField*) textField{
NSLog(@"The content has been removed.");
return YES;
}
// 键盘上的return 按钮
-(BOOL) textFieldShouldReturn:(UITextField*) textField{
[textField resignFirstResponder]; // 隐藏输入键盘
return YES;
}
UITextField实例:
UITextField *textfield = [[UITextField alloc] initWithFrame:CGRectMake(0, 20, 320, 240)];
textfield.autocapitalizationType = UITextAutocapitalizationTypeNone; // 禁止首字母大写
textfield.keyboardType = UIKeyboardTypeNamePhonePad; // 设置键盘类型
textfield.borderStyle = UITextBorderStyleRoundedRect; // 输入框的边框类型
textfield.delegate = self; // 设置委托代理
textfield.returnKeyType = UIReturnKeyDone; // 键盘上的return按钮类型
textfield.secureTextEntry = NO; // 是否安全输入,若设置为YES,则显示的输入内容为星号
textfield.clearButtonMode = UITextFieldViewModeAlways; // 清除按钮模式
textfield.textColor = [UIColor redColor]; // 输入框中的文本颜色
textfield.font = [UIFont boldSystemFontOfSize: 14]; // 输入框的字体
5. UISlider
功能:控制声音大小,或是表示播放进度等
部分属性
@property(nonatomic) float value; // 设置获取slider 的 value 值
@property(nonatomic) float minimumValue; // 设置slider 的最小值
@property(nonatomic) float maximumValue; // 设置slider 的最大值
@property(nonatomic , retain) UIImage *minimumValueImage; // 设置图片数量的最小值
@property(nonatomic , retain) UIImage *maximumValueImage; // 设置图片数量的最大值
-(void) setValue:(float)value animated:(BOOL)animated; // 设置slider 的value值,是否存在动画
UISlider实例:
UISlider *slider = [[UISlider alloc] initWithFrame: CGRectMake(20, 20, 100, 100)];
[slider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
slider.maximumValue = 100;
slider.minimumValue = 0;
slider.value = 50;
6. UISegmentedControl
功能:可用于页面的切换,
UISegmentedControl 实例:
NSArray *array = [NSArray arrayWithObjects:@"Tom",@"Jim",@"jack",nil];
UISegmentedControl *segmentCtrl = [UISegmentedControl alloc] initWithItems: array];
segmentCtrl.frame = CGRectMake(0, 0, 230, 140);
segmentCtrl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentCtrl.selectedSegmentIndex = 0;
[segmentCtrl addTarget: self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
7. UIPageControl
功能:通常和UIScrolView连用, 提示用户当前显示的页数
属性及方法
@property(nonatomic) NSInteger numberOfPages; // 分页的“小圈”数
@property(nonatomic) NSInteger currentPage; // 显示当前的页
@property(nonatomic) BOOL hidesForSinglePage; // 只存在一页时,是否隐藏“小圈”, 默认为YES
-(void) updateCurrentPageDisplay; // 刷新视图
8. UIActivityIndicatorView
功能:提示用户当前页正在加载数据
部分属性和方法
@property(nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle;
// 设置风格
@property(nonatomic) BOOL hidesWhenStopped;// 停止时,隐藏该加载提示视图,默认为YES
@property(readwrite, nonatomic, retain) UIColor *color; // 修改该视图的颜色
-(void) startAnimating; // 开始动画
-(void) stopAnimating; // 停止动画
-(BOOL) isAnimating; // 判断动画的状态
UIActivityIndicatorViewStyle 实例:
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(20, 20, 40, 60);
[activityView startAnimating];
9. UIAlertView
功能:显示必要的提示信息,在某些时刻给出警示
UIAlertView 实例:
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: @"标题"
message: @"提示的文本信息"
delegate: self
cancelButtonTitle: @"取消"
otherButtonTitles: @"确定", nil];
[alertView show];
[alertView release];
10. UIImageView
功能:专门用于显示图片的视图
部分属性和方法
-(id) initWithImage:(UIImage*)image; // 初始化图片
-(id) initWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage;
// 初始化带高亮的图片
@property(nonatomic , retain) UIImage *image; // 点语法设置图片
@property(nonatomic , retain) UIImage *highlightedImage; // 点语法设置高亮图片
@property(nonatomic , getter=isUserInteractionEnabled) BOOL userInteractionEnabled;
// 是否打开用户交互, 默认为NO
UIImageView 实例:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,20,60)];
imageView.image = [UIImage imageNamed:@"photo.png"];
imageView.userInteractionEnabled = YES;