《Objective-C基础教程》读书笔记

Objective-C简介

Objective-C是一种面向对象的高级编程语言,它扩展了标准的ANSI C编程语言,将Smalltalk式的消息传递机制加入到ANSI C中。它是Apple的OS X和iOS操作系统及其相关API(Application Program Interface)、Cocoa(包含Foundation和AppKit框架,是Mac OS X的应用程序开发环境)和Cocoa Touch(包含Foundation和UIKit框架,是iOS的应用程序开发环境)的主要编程语言。

#import与#include

  • include是C/C++中用来包含结构体、符号常量、函数原型等元素的声明。#import的作用和#include类似,是OC中用来引用其他文件的声明。
  • 两者的区别是#import可以保证头文件只被包含一次,无论此命令在该文件中出现了多少次。但是#include不行,如果不使用头文件卫士
    (Header File Safeguard),当同一个头文件被重复导入,会报重复定义的错误。
// 头文件卫士使用,#ifndef是"if not defined"的简写,“标示”要保证全局唯一
#ifndef 标示
#define 标示
#include XXX.h
#include XXX.h
#endif

BOOL

  • 许多编程语言都支持布尔(Boolean)类型,它指的是可以存储真值和假值得变量类型,C语言拥有布尔类型bool,OC中提供了一个相似的类型BOOL
  • OC中的BOOL实际上是一种带符号的字符类型(signed char)的类型定义(typedef),它使用8位存储空间。
  • BOOL具有YES和NO两个值,OC通过#define指令把YES定义为1,NO定义为0。但编译器并不会将BOOL当做仅仅能保存YES和NO的真正布尔类型,编译器仍然将BOOL认作8位的二进制数。
  • 同C语言一样,OC中0为false,非0都为true。这意味着,BOOL类型的变量不能通过与YES比较来判断其是否为true,因为YES就是1,不等于1并不能表示其为true或false。可以和NO进行比较,因为NO是0,如果不等于NO,就是不等于0,也就是true。
  • 如果不小心将一个大于1字节的整型值(int或short)赋给一个BOOL类型的变量,那么只有低位的字节会用作BOOL值
// 为BOOL值赋值int,并打印的过程演示
// 提示:计算机中存储数据和数据计算时用的都是对应的补码,int型是32位二进制
/******************赋值小于1字节时**********************/
BOOL bool01 = 127;
// 初始值127是32位正整数,其补码与原码相同
// 32位原码:0000 0000 0000 0000 0000 0000 0111 1111
// 32位补码:0000 0000 0000 0000 0000 0000 0111 1111

 // 给BOOL值赋值时,是将32位赋值给8位,高位赋值给低位直接截取
 // 32位截取8位后的补码:0111 1111
        
 // 打印时,是将BOOL值赋值给32位,再转成原码输出,这里8位的补码是正数,低位转高位时前面补0
 // 赋值给32位时的补码:0000 0000 0000 0000 0000 0000 0111 1111
 // 赋值给32位的原码:  0000 0000 0000 0000 0000 0000 0111 1111  最后转成十进制输出是127
        
 NSLog(@"bool01 = %d", bool01);
  // %d是指按带符号32位二进制的数字转成十进制输出

 BOOL bool02 = 128;
 // 32位原码:0000 0000 0000 0000 0000 0000 1000 0000
// 32位补码:0000 0000 0000 0000 0000 0000 1000 0000
// 8位截取后的补码:1000 0000 截取后变成负数
// 打印时8位转32位,由于低位是负数,转高位时补1
// 赋值给32位的补码:1111 1111 1111 1111 1111 1111 1000 0000
// 赋值给32位的原码:1000 0000 0000 0000 0000 0000 1000 0000  最后转成十进制是-128
NSLog(@"bool02 = %d", bool02);
 
 /******************赋值大于1字节时**********************/
 BOOL bool03 = 256;
// 32位原码:0000 0000 0000 0000 0000 0001 0000 0000
// 32位补码:0000 0000 0000 0000 0000 0001 0000 0000
// 8位截取后的补码:0000 0000
 // 赋值给32位的补码:0000 0000 0000 0000 0000 0000 0000 0000
 // 赋值给32位的原码:0000 0000 0000 0000 0000 0000 0000 0000  最后转成十进制是0
 NSLog(@"bool03 = %d", bool03);
控制台打印信息

启动参数

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // ...
    }
    return 0;
}
  • 上面代码为一个OC程序的主函数,其中argc为启动参数的个数,argv[]为启动参数的数组
  • argue[0]为程序名,所以argc至少是1
  • 在Xcode中为程序添加启动参数:Product -> Edit Scheme -> Arguments ->Arguments Passed On Launch


    《Objective-C基础教程》读书笔记_第1张图片
    添加启动参数.png

方法的调用

  • 方法的调用又被称为发送消息,一般形式如下:
[obj message];

它可以理解为向obj这个对象发送了一条message消息。

  • 当这条消息发出时,obj对象会根据其内部的isa指针找到它对应的类,再通过类中指向在类中定义的方法的代码的指针,找到能够响应这条消息的方法并执行(如果没有找到,会到其超类中寻找,以此类推直到NSObject)
  • 在OC中调用方法时(发送消息时),一个名为self的隐藏参数将被传递给接受对象,而这个参数的引用就是该接受对象。例如上面执行的[obj message]中,obj作为其self参数进行传递。这个隐藏参数的作用是,当方法中引用实例变量时,实际上做的是类似于下面的操作(假设property为obj的一个实例变量):
    self -> property
  • OC中为什么不直接通过对象指向各自的代码,而非要通过类对象?其实有很多OOP的系统的确是这样做的,但是拥有类对象的好处也是非常明显的,当在运行时改变某个类,则该类的所有对象都会自动继承这些变化

面向对象的原则(Open/Close Principle)

对扩展开放,对修改关闭

继承

  • OC中只支持单继承,不支持多继承。OC可以通过Category和protocol来实现多继承的效果
  • super是编译器提供的一个功能,当向super发送消息时,实际上是向OC请求向该类的超类发送消息,如果该类的超类没有定义这个消息,就会沿着继承链继续往上寻找

NSLog( )打印对象

  • NSLog( )可以使用%@说明符来输出对象,从本质上讲,利用NSLog( )输出对象就相当于NSLog( )给对象发送了一条description消息,输出内容即为description方法的返回值
  • 可以通过重写类的description方法来实现NSLog( )输出对象时,打印出我们需要了解的内容

存取方法名规范(getter/setter)

  • setter方法会根据需要修改的属性名来命名,并加上set前缀,书写采用驼峰式,例如setName:、setSex:等
  • getter方法是以其返回的属性名来命名,上面的setter方法对应的getter方法名为name,sex
  • 注意不要将getter方法加上get前缀,get前缀在OC中具有特殊的意义。如果get前缀出现在Cocoa的方法名中,就意味着这个方法会将参数作为指针来返回数值。例如NSData中getBytes:方法,它的参数就是用来存储字节的内存缓冲区的地址。

// 未完待续。。。

你可能感兴趣的:(《Objective-C基础教程》读书笔记)