关于Objective-C

一、distinction

Objective-C的原意就是在C语言主体上加入面向对象的特性。

import 是oc导入头文件的关键字,#import会自动导入一次,不会重复导入,不会引起交叉编译。

.h 头文件:包含类,类型,函数和常数的声明。
.m 源代码文件。

Objective-C方法与函数的区别:
方法是唯对象所有
函数是不依赖于对象存在的
所有的实例方法默认都是公有的

Objective C的重要数据类型:
NSString字符串
CGfloat 浮点值的基本类型
NSInteger 整型
BOOL 布尔型

二、基本语法

1、字符串

NSString* myString = @"My String\n";
NSString*  fromCString = [NSString stringWithCString:"A C string" 
encoding:NSASCIIStringEncoding];

NSString* anotherString = [NSString stringWithFormat:@"%d %@", 10, @"hello"];
NSLog(@" %@ ",anotherString);

2、方法
带一个参数的方法:

- (double)pi;
- (int)square:(int)num;
NumUtil *n = [NumUtil new];
[n square:2];

带多个参数的方法:

- (void)setX:(double)x andY:(double)y {  
    self.x = x;  
    self.y = y;  
}  

//new
 Point2D *p1 = [[Point2D alloc] init];  
//调用 
[p1 setX:0 andY:0];  

方法的声明必须写在@interface-@end之间,实现必须写在@implementation-@end之间

3、Interface

@interface MyObject : NSObject {
    int memberVar1; // 实体变量
    id  memberVar2;
}

+(return_type) class_method; // 类方法
-(return_type) instance_method2: (int) p1; // 实例方法
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end

加号(+)代表类方法(class method),不需要实例就可以调用,与C++ 的静态函数相似。
减号(-)即是一般的实例方法。

类的声明

4、Implementation
Interface区块内的实体变量默认权限为protected,宣告于implementation区块的实体变量则默认为private。

@implementation MyObject {
  int memberVar3; //私有变量
}

+(return_type) class_method {
    ....
}
-(return_type) instance_method1 {
     ....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
    ....
}
@end

@private 私有成员
@protected 受保护成员,只有当前类或子类可以访问
@public 公共成员

5、创建对象
alloc 分配内存
allocate[ˈæləkeɪt]分配给 allot 拨给

MyObject * my = [[MyObject alloc] init];

//若创建对象不需要参数
MyObject * my = [MyObject new];

6、a represantative example

-(void) insertObject: (id)AAA atIndex:(NSInteger) BBB
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];

[myAppObject getArray]//获得数组MyArray
[myAppObject getObjectToInsert]获得插入的对象anObj
[myArray insertObject:anObj atIndex:0];实际结果

在Objective-C 中,id 类型是一个独特的数据类型。在概念上,类似Java 的Object 类,可以转换为任何数据类型。

7、数组
NSMutableArray 和 NSArray 是 ObjectiveC 中使用的数组类,前者是可变数组,后者是不可变数组。

NSMutableArray *aMutableArray = [[NSMutableArray alloc]init];
[anArray addObject:@"哈哈哈哈"];

//nil结束
 NSArray *array4 = [[NSArray alloc] initWithObjects:@"AAA", @"bbb", nil]; 
 NSLog(@"%@", array4);  

8、字典
NSMutableDictionary)是由键-值对组成的数据集合.正如,我们在字典里查找单词的定义一样.
通过key(键),查找的对应的value(值),key通常是字符串对象,也可以是其他任意类型对象。

NSMutableDictionary*aMutableDictionary = [[NSMutableArray alloc]initWithCapacity:0];
[aMutableDictionary setObject:@"firstobject" forKey:@"aKey"];



NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2"};
NSDictionary *dictionary2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1", @"key1",
                            @"value2", @"key2", nil];

NSDictionary *dictionary4 = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1",
                                 @"value2", @"key2", nil];

字典的一些操作

[dictionary count];//作用:字典中元素个数
 [dictionary objectForKey:@"key1"];  //作用:根据key找对应value

    //作用:获取字典中所有的key返回是一个数组
    [dictionary allKeys];

9、Category 类别
类别用于对已存在的类添加新的方法。可以保证类的原始设计规模最小,功能增加在逐步扩展。
使用Category对类进行扩展时,不需要创建子类。

@interface ClassName(CategoryName)
//method declarations
@end

@implementation …… 

category和extensions的不同在于后者可以添加属性。

10、@property&&@synthesize
@property:在@interface自动生成getter和setter方法的声明
@synthesize:在@implementation自动生成getter和setter方法的实现

@property(nonatomic,retain)Shape *all;

readwrite是可读可写特征;生成getter方法和setter方法;
readonly是只读特性,只生成getter方法.
assign做的事情其实就是拷贝了指针。让这个属性只是复制你所赋给它的值的指针。于是,它们就共同指向了同一个区域了。
retain retain属性就是为了解决上述问题而提出的,使用了引用计数,还是上面那个例子,我们给那块内存设一个引用计数,当内被分配并且赋值给a时,引用计数是1.当把a赋值给b时引用计数增加到2.这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1.当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以直接释放掉。此时系统自动调用dealloc函数,内存被回收。
retain 保持

copy就是新创建一块内存区域,复制变量的内容进来,只是保证了变量的内容相同。

Strong 只要某一对象被一个strong指针指向,该对象就不会被销毁。
nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。不安全,但是效率高。

默认关键字,基本数据: atomic,readwrite,assign

11、代码块Block
block:本质就是一个[object-c对象]

Block:- 匿名函数 - 截获自动变量
Block还可以保存一段代码,在需要的时候调用

int (^sumOfNumbers)(int a, int b) = ^(int a, int b) {
    return a + b;
};

Block作为函数参数:

[……  animations: ^{
    cell.center = center;}
    completion: ^(BOOL finished) {
    NSLog("animation %@ finished", finished? @"is": @"isn't");
}];

这里面就用到了void(^ animations)(void)跟void(^completion)(BOOL finished)两个block

12、构造函数

- (instancetype)initWithName:(char *)name age:(int)age{
    
    self = [super init];//先继承再说
    if (self) {        
        _age = age;
        _name  = name;
    }
    return self;
}

三、questions and answers:

1、 Object-c的类可以多重继承么?可以实现多个接口么?
Object-c的类不可以多重继承;
可以实现多个接口,通过实现多个接口可以完成C++的多重继承。

2、原子(atomic)跟非原子(non-atomic)属性有什么区别?
atomic提供多线程安全。防止在写未完成的时候被另外一个线程读取,造成数据错误
non-atomic在自己管理内存的环境中,那么访问器只是简单地返回这个值。

3、如何理解MVC设计模式
Model负责存储、定义、操作数据;

View用来展示书给用户,和用户进行操作交互;

Controller是Model和View的协调者,Controller把Model中的数据拿过来给View用。Controller可以直接与Model和View进行通信,而View不能和Controller直接通信。
View与Controller通信需要利用代理协议的方式,当有数据更新时,Model也要与Controller进行通信,这个时候就要用Notification和KVO,这个方式就像一个广播一样,Model发信号,Controller设置监听接受信号,当有数据更新时就发信号给Controller

4、NSInteger 与 int的区别
NSInteger能够自动匹配, 在32位App中,NSInteger是32位整型,在64位App中,NSInteger是64位整型.

6、堆&栈
栈内存系统分配
堆内存自己申请

栈:存局部变量、函数参数
堆:new malloc申请的变量

全局变量和静态变量的存储是放在一块的。

7、null与nil
NULL是宏,是对于C语言指针而使用的,表示空指针
nil是宏,是对于Objective-C中的对象而使用的,表示对象为空

8、C++和OC的区别?
@interface 变量默认的访问权限就是 protected

OC中的对象不能直接拿到,只能通过内存地址去操作对象

c++中就有了 值传递 与指针传递的区别。在java中是没有的,oc中也是没有的,因为java与oc创建的对象都相当于是创建的对象的指针而不能直接的创建对象本身,都是通过这个指针去访问对象的。

在C++中,下面三种对象需要调用拷贝构造函数

  1. 一个对象作为函数参数,以值传递的方式传入函数体
  2. 一个对象作为函数返回值,以值传递的方式从函数返回;
  3. 一个对象用于给另外一个对象进行初始化(常称为复制初始化

oc中虽然不能直接的创建对象,但是oc中函数调用,以及返回的时候,传入的参数一样会拷贝一份出来,只不过这个拷贝是一个指针,而不是拷贝的一个对象。返回的时候一样是拷贝的一个副本,这个副本是指针。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容