一位Android工程师的 ios 学习笔记

最近由于工作需求学了些Object-C语法,开发了一段时间IOS,对于我这个从Android转到IOS的人,我感觉IOS还是挺麻烦的,XCode用着也不顺手,Mac系统感觉还是没Windows方便。在学习过程中,写了一些小笔记,零零散散在这里整理记录一下。写的不是很全,以后遇到了再做补充。

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个是单步)

debug

XCode中的全局搜索在这个位置
search
点击代码左侧行号可以添加断点,查看已添加的断点在如下图所示的蓝色五边行按钮(我刚开始还以为是书签)
断点

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:退出一个界面携带动画

猜你喜欢

转载自blog.csdn.net/qq_27070117/article/details/79049905