ObjectC 语法
ObjectC文件后缀:
- .m 源文件代码, 可以包含 ObjC 和 C 代码
- .mm 源文件代码, Objective-C 和 C C++ 混编代码
- .pl Perl 源文件代码
- .o 编译后的 Object文件, 相当于 Java .class文件
ObjC 中 #import 可以替代 C 中的 #include , 但它可以保证头文件只被声明一次
标识符:
- ObjC 中, 标识符不能包含 $ 美元符号, 跟Java相似, 不能以数字开头, 不能是关键字
注释:
- 单行注释: //
- 多行注释: /**/
注意: 多行注释不能嵌套
关键字:
- self 关键字相当于 Java中的 this
- static 关键字可以用在方法中, 方法中的变量使用该关键字,那么该变量在第一次调用时会被创建, 在方法调用结束不会被销毁, 下次调用不用定义直接使用, 他的值也会被保存
- typedef 用户定义的数据类型以及赋予一个名字
- static 关键字修饰的局部变量
- extern 表明这条语句是变量的声明, 不是赋值
- enum 枚举类型
- __weak 弱引用
- __strong 强引用(默认强引用)
- __unsafe_unretained 弱引用
- __autoreleasing 延迟释放对象
- YES boolean 类型true
- NO boolean 类型 false
- BOOL boolean类型
方法语法:
-
方法调用:
[obj method: argument];
obj: 对象 method: 方法名 “:” 替代 “()”, argument: 参数
[car fly]
car 是对象, fly 是行为, 加入 car 对象中有 fly 方法, 则会执行 fly 方法, 假如没有, 编译不会报错, 但运行会报异常
- 方法声明:
+(int) class_method; //+ 代表 类方法 相当于Java的静态方法 - 代表实例方法 需要有对象才能调用 以分号结尾的必须在 @interface 里使用
-(float) instance_method1{} // 有实体内容的必须在 @implementation 中使用
ObjC 中的字符串对象:
-
NSString:
NSString* myString = @"My String\n"; NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];
使用助记符 @ 来从常量池创建字符串 即 myString 是常量
从一个C语言字符串创建Objective-C字符串
NSString* fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding]; ???
ObjC中的"类":
定义(interface)与实现(implementation)
定义即接口, 实现即接口的实现
@interface 跟 @implementation 后跟的名称可以不同, 但他们所在的两个文件名必须相同
-
ObjC @interface 语法:
接口以 @interface 开始 , 以 @end 结束
冒号 “:” 代表继承 , 相当于 Java 类都继承 Object 类, NSObject 是所有的父类, 接口名即 MyObject , 不是 NSObject@interface MyObject : NSObject { int memberVar1; // 实体变量 接口中变量默认访问权限是 protected id memberVar2; } +(return_type) class_method; //+ 代表 类方法 相当于Java的静态方法 -(return_type) instance_method1; // - 代表实例方法 需要有对象才能调用 -(return_type) instance_method2: (int) p1; -(return_type) instance_method3: (int) p1 andPar: (int) p2; @end
接口跟实现的对应关系: 根据文件名
@implementation MyObject { int memberVar3; //私有實體變數 实现中默认访问权限是 private // 大括号中生命的变量是成员变量 } +(return_type) class_method { .... //method implementation } -(return_type) instance_method1 { .... } -(return_type) instance_method2: (int) p1 { .... } -(return_type) instance_method3: (int) p1 andPar: (int) p2 { .... } @end
ObjC创建对象:
//alloc的作用是分配内存,init则是初始化对象。 init与alloc都是定义在NSObject里
//静态方法 alloc , [MyObject alloc] 返回 MyObject 对象, 然后 init 实例方法 , 作用初始化并返回 MyObject 对象
MyObject * my = [[MyObject alloc] init];
//在Objective-C 2.0里,若创建对象不需要参数,则可直接使用new
MyObject * my = [MyObject new];
//可以重写 init方法, 做一些额外的事情, 相当于 Java中的构造方法
ObjC 方法:
[myArray insertObject:anObj atIndex:0];
//myArray 是方法调用者, 实例对象或者如果是静态方法, 可以是类名
//insertObject 是方法名之一, ObjC中方法名跟参数可以交叉声明, 比如上边的例子, anObj是参数, atIndex 也是方法名之一, 0 也是参数
// ObjC 中的方法叫做消息 , 即使类 或实例中没有这个消息也不会报编译错, 但运行时会抛异常
-(void)TestString:(NSString*)firsParam, ... ;
//接收String类型的多个参数
-(void)TestObject:(id)firsParam, ... ;
//接收任意类型的多个参数
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
//分析: myAppObject实例中有 getArray 方法, 返回一个对象, 调用该对象中 insertObject 方法,
//传入两个参数, 参数1 是 调用 myAppObject 中的方法 getObjectToInsert 返回的对象, 参数2 是 int 类型 atIndex
// 当给类发消息,你指定的方法必须被定义为类方法,而不是实例方法。 意思就是当调用了静态方法, 该方法的声明也必须是静态的
NSMutableArray* myArray = nil; // nil 基本上等同于 NULL
// 创建一个新的数组,并把它赋值给 myArray 变量
myArray = [NSMutableArray arrayWithCapacity:0];
ObjC 属性:
再 objC 的一个对象中, 首个大括号中声明的变量是成员变量
如:
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
@implementation Person
@synthesize name;
@dynamic age;
-(id)initWithAge:(int)initAge
{
age = initAge; // 注意:直接赋给成员变量,而非属性
return self;
}
-(int)age
{
return 29; // 注意:并非返回真正的年龄
}
@end
ObjC 中的数据类型:
基本的跟C类似
BOOL 布尔类型, value 为 YES or NO
NSString a = @"aaa"; //@ 代表常量
id类型: 相当于Java中的Object类型,所有引用数据类型都是id类型,基础类型本身不是id类型,但转为其包装类型后也是id类型
ObjC 中的异常处理:
@try{
}@catch(NSException *exception){
NSLog(@"exception: %@%@",[exception name], [exception reason]);
}
协议:
定义:
协议是一组没有实现的方法列表,任何的类均可采纳协议并具体实现这组方法。
类似Java中的接口
语法:
以 @protocol 开始 , 以@end结束, 中间为方法列表。
@protocol Locking
- (void)lock;
- (void)unlock;
@end
块的概念: 类似java的匿名内部类
块的声明语法:
returntype (^blockName)(argumentType);
块的实现语法:
returntype (^blockName)(argumentType)= ^{};
块的调用使用:
returntype a = blockName(argument);
块类似方法, 有参数返回值可以被调用
类型定义块:
#import <Foundation/Foundation.h>
typedef void (^CompletionBlock)();
@interface SampleClass:NSObject
- (void)performActionWithCompletion:(CompletionBlock)completionBlock;
@end
@implementation SampleClass
- (void)performActionWithCompletion:(CompletionBlock)completionBlock{
NSLog(@"Action Performed");
completionBlock();
}
@end
int main(){
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass performActionWithCompletion:^{
NSLog(@"Completion is called to intimate action is performed.");
}];
return 0;
}
OBJC中的结构体:
结构体的定义:
struct [StructName]
{
member definition;
member definition;
...
member definition;
} [one or more structure variables];
使用, 例如:
struct Book{
NSString bookName;
NSString autor;
};
int main(){
struct Book book1;
struct Book book2;
book1.bookName = @"冰与火之歌";
book1.autor = @"马丁·乔治";
book2.bookName = @"啦啦啦";
book2.autor = @"hehe";
NSLog(@"Book 1 author : %@", book1.author);
NSLog(@"Book 1 author : %@", book2.author);
}
位域:
struct packed_struct {
unsigned int f1:1;//数字代表 后位长度变量 即变量所占的位数
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;
ObjC的预处理指令:
...待补充
其他:
@autoreleasepool 自动释放池 @autoreleasepool{} 括号内声明的变量可以自动释放
@private 私有方法属性
@public 公有方法属性
@property 在 @interface 文件里的属性使用该指令, 在其实现部分就不需要再次定义属性
@synthesize 使用@synthesize 关键字表明 由属性的声明自动的产生一对访问方法
@dynamic 使用@dynamic 关键字表明访问方法会由程序员手工提供
int a = 1;
int b = 2;
NSLog(@"Hello World!%i,%i",a,b); ??? 方法?
ObjC 中的指针:
// * 代表 obj 仅仅存储了 NSObject 对象的一个引用, 并没有存储他的值
NSObject * obj = [[NSObject alloc] init];
NSLog 类型 format 表:
NSLog 中 "%%" % 百分号转义百分号(C Java也这么写)
┌─────────────────────────┬───────────────────────┐
│ char │ %c │
├─────────────────────────┼───────────────────────┤
│ short int │ %hi %hx %ho │
├─────────────────────────┼───────────────────────┤
│ unsigned short int │ %hu %hx %ho%hu %ho │
├─────────────────────────┼───────────────────────┤
│.... │ │
└─────────────────────────┴───────────────────────┘
NSObject:
- int retainCount //引用计数器
- - (void) retain; // 该方法手动调用可以使引用计数器加1
- + (void) alloc; // 创建对象分配内存
- - (void) init; // 初始化
- - (void) release;// 手动调用可以使引用计数器减1 如果 retainCount 为0 ,则释放掉
NSString:
- - (void) initWithString:(NSString) string; //初始化NSString
- - (void) stringByAppendingString:(NSString) string; //追加字符串
- - (void) stringWithFormat:(id)firsParam, …; //格式化
- - (void) isEqualToString:(NSString)string; //字符串对比
- - (BOOL) hasPrefix:(NSString)string; //类似Java string.startsWith
- - (BOOL) hasSuffix:(NSString)string; //类似Java string.endsWith
NSDictionary 不可变字典
NSMutableDictionary 可变字典,相当于map集合
初始化可变字典:
NSMutableDictionary *mutable_Dic = [NSMutableDictionary dictionary];
往可变字典中添加元素:
[mutable_Dic setObject:value(id)(不可为nil) forKey: key];
[mutable_Dic setValue: value(id)(可为nil) forKey:key];
@{} @[]
- @{}:初始化不可变数组
- @[]:初始化不可变字典
XCode:
Xcode关闭ARC:
ARC:自动引用计数
1. 创建工程时关闭:创建工程时去掉Use Automatic Reference Counting 的对勾
2. 在工程设置 Build Settings选项卡搜索 garbage 关键字, 将Objctive-C Automatic Reference Counting 选项置为 NO(关) 即可关闭自动引用计数
3. 关闭某个文件的ARC 引用计数: 在工程设置 Build Phases 选项卡, Compile Sources 标签, 在不需要自动引用计数的文件后双击加入 “-fno-objc-arc” Compiler Flags 即可
XCode常用快捷键:
command+L --> 跳转
command+F --> 搜索
option(alt)+左右方向键 --> 光标在单词之间移动
fn+F6 --> 代码单步调试(调试我就记得这么一个,一般都是直接点按钮的, 如图,第三个按钮为跳过当前断点执行下一个断点,第5个是单步)
XCode中的全局搜索在这个位置
点击代码左侧行号可以添加断点,查看已添加的断点在如下图所示的蓝色五边行按钮(我刚开始还以为是书签)
IOS 界面基础:
IBOutlet:
一般放在控件对象声明的前面,类似Android 中 butterknift 的@Bind 注解
作用是告诉编译器,这个变量是个控件,需要跟布局文件(storyborad)中的相关控件进行关联
也叫"插座变量"
IBAction: 被它修饰的方法为事件的响应方法 类似Android中的点击事件
NSButton: 按钮 (Android中的Button)
NStextField: 文本条(Android中的TextView)
布局界面 xib nib 文件:
xib 文件是 XML文件 , 类似Android中的 layout XML 布局文件, 用来解决代码编写界面的不便, 而xib文件编译后生成 nib 文件
-
UIWindow
-
UIViewController
视图控制器 , 类似Android中的Activity
生命周期方法:alloc (构造)创建对象,分配空间 init (initWithNibName) (构造)初始化对象,初始化数据 loadView (setContentView)从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图 viewDidLoad (onCreate)载入完成,可以进行自定义数据以及动态创建其他控件 viewWillAppear (onStart)视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了 viewDidAppear (onResume)视图已在屏幕上渲染完成 viewWillDisappear (onPause)视图将被从屏幕上移除之前执行 viewDidDisappear (onStop)视图已经被从屏幕上移除,用户看不到这个视图了 dealloc (onDestory)视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放 该方法为 NSObject中的方法, 当引用计数为0时会调用dealloc方法进行释放内存 (括号中仅仅是跟 Android 粗略对比, 并不完全准确)
-
UIView
-
UIApplication
-
可以获得UIApplication单例对象
-
创建图标右上小红点消息数量提示
UIApplication *app = [UIApplication sharedApplication]; UIApplication *app = [UIApplication sharedApplication]; app.applicationIconBadgeNumber = 10; // 创建通知对象 UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; // 注册用户通知 [app registerUserNotificationSettings:setting]; // AppDelegate:监听应用程序的生命周期 // 以下方法就是应用程序的生命周期方法
AppDelegate文件就是UIAppliacation的代理,我们可以发现它已经遵守了UIApplicationDelegate:
// 应用程序启动完成的时候就会调用AppDelegate的方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"%s",__func__); return YES; } // 当应用程序失去焦点的时候调用 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"%s",__func__); } // 当应用程序进入后台的时候调用 - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"%s",__func__); // 保存一些信息 } // 当应用程序进入前台的时候调用 - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"%s",__func__); } // 当应用程序完全获取焦点的时候调用 // 只有当应用程序完全获取焦点的时候,才能够与用户交互 - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"%s",__func__); } // 当应用程序关闭的时候 - (void)applicationWillTerminate:(UIApplication *)application { } //收到内存警告时调用 -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{ }
-
切换控制器UITabBarController
导航控制器UINavigationController
PresentViewController 进入新界面并携带动画
dismissViewControllerAnimated:completion:退出一个界面携带动画