简述OC基础语法的一些坑洞

作者: iOS佥 | 来源:发表于2018-03-21 21:35 被阅读5次

1. 标识符的规则

  1. 字母、数字、下划线、美元符$,但是不能以数字开头;
  2. 区分大小写
  3. 不能是关键字

2. #import 和 #include 的区别

  • include 的作用就是将指定的源代码插入到当前源代码的位置,如果导致了重复导入,不会给出提示

  • Objective-C 提供的 #import 更加智能,可以帮助程序员判断,避免重复导入的问题

3. OC 的块

OC 的块类似 Swift 的闭包,像一个匿名函数B,在定义的时候无须指定名字,通常的用法是作为函数A的参数,在调用 A 的时候实时定义 B,使得代码更加灵活:

#import <Foundation/Foundation.h>
typedef void (^FKProcessBlock)(int);  // 定义一个块类型
// 使用FKProcessBlock定义最后一个参数类型为块
void processArray(int array[] 
    , unsigned int len, FKProcessBlock process)
{
    for(int i = 0 ; i < len; i ++)
    {
        process(array[i]);  // 将数组元素作为参数调用块
    }
}
int main(int argc , char * argv[])
{
    @autoreleasepool{
        int arr[] = {2, 4, 6};  // 定义一个数组
        // 传入块作为参数调用processArray()函数
        processArray(arr , 3 , ^(int num)
        {
            NSLog(@"元素平方为:%d" , num * num);
        });//注意这里大括号中的是块的定义
    }
}

4. id类型

id类型是Objective-C提供的一个特有类型,这个类型可以代表所有对象的类型,也就是说,任意类的对象都可以赋值给id类型的变量
当通过id类型的变量来调用方法时,Objective-C会执行动态绑定,在程序运行时自动判断对象所属的类,确定需要动态调用的方法

5. 单例模式 Singleton

某些时候,我们要使用的类只用到一个实例,例如一个窗口管理器,这时候就可以用到单例类,保证这个类始终只能创建一个对象。常用写法:

// 接口部分
#import <Foundation/Foundation.h>  
  
@interface Singleton : NSObject  
  
+(instancetype) shareInstance ;  
  
@end  
  
  
// 实现部分
#import "Singleton.h"  
  
@implementation Singleton  
/*
 用 static 全局变量实现,每次程序获取该实例前都要先判断该 static 全局变量是否为 nil:
 如果为 nil 就初始化实例;
 如果不为 nil,程序直接返回该全局变量指向的实例。
*/
static Singleton* _instance = nil;  
  
+(instancetype) shareInstance  
{  
    static dispatch_once_t onceToken ;  
    dispatch_once(&onceToken, ^{  
        _instance = [[self alloc] init] ;  
    }) ;  
      
    return _instance ;  
}  
  
@end 

// 测试程序
#import "Singleton.h"

int main(int argc , char * argv[]) {
    @autoreleasepool{
    // 判断两次获取的实例是否相等,程序将返回1(代表真)
    NSLog(@"%d", [Singleton instance] == [[Singleton instance];
    }
}

测试程序如下

6. 访问控制符

OC中提供了4个访问控制符:@private @package @protected @public。

  • @private(当前类访问权限):成员只能在当前类内部可以访问,在类实现部分定义的成员变量相当于默认使用了这种访问权限。
  • @package(同映像访问权限):成员可以在当前类或和当前类实现的同一映像中使用。同一映像就是编译后生成的同一框架或同一个执行文件。
  • @protected(子类访问权限):成员可以在当前类和当前类的子类中访问。在类接口部分定义的成员变量默认是这种访问权限。
  • @public(公共访问权限):成员可以在任意地方访问。
@private @packge @protected @public
同一个类中
同一个映像中
子类中
全局范围

7. 合成存取 @property

系统自动合成 setter 和 getter 方法:

  1. 在接口部分 @interface@end 之间使用 @property指令 定义属性(无须放在花括号中);
  2. (可选)在类实现部分使用 @synthesize指令 改变对应的成员变量名。

8. @property 指示符

①. atomic/nonatomic 线程管理

指定合成存取方法是否为原子操作,可以理解为是否线程安全,但在iOS上即时使用atomic也不一定是线程安全的。
可以发现几乎所有代码的属性设置都会使用nonatomic,这样能够提高访问性能,在iOS中使用锁机制的开销较大,会损耗性能。


②. readwrite/readonly 读写端丽

  • readwrite是编译器的默认选项,表示自动生成getter和setter,如果需要getter和setter不写即可。
  • readonly表示只合成getter而不合成setter。

③. assign,retain,strong,weak,copy,unsafe_unretained 内存管理

  • assign: 简单赋值,不更改索引计数(Reference Counting)。适用于基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)。
  • retain:释当把某个对象赋值给该属性时,该属性原来所引用的对象的引用计数减1,被赋值对象的引用计数加1。在未启用ARC机制的的情况下,retain可以保证一个对象的引用计数大于1时,该对象不会被回收。启用ARC后一般较少使用retain。
  • strong 指示符该属性对被赋值对象持有强引用,强引用的意思是:只要该强引用指向被赋值的对象,那么该对象就不会自动回收。
  • weak 指示符该属性对被赋值对象持有弱引用,弱引用的意思是:即使该弱引用指向被赋值的对象,该对象也可能被回收。
  • copy:如果使用copy指示符,当调用setter方法对成员变量赋值时,会将被赋值的对象复制的一个副本,再将该副本给成员变量,相应的原先的被赋值的对象的引用计数加1。当成员变量的类型是可变类型,或其子类是可变类型,被赋值的对象在赋值后有可能再被修改,如果不需要这种修改,则可以考虑copy指示符。
  • unsafe_unretained:与weak不同,被unsafe_unretained指针所引用的对象被回收后,unsafe_unretained指针不会被赋为nil,可能会导致程序出错。

9.类别,拓展

当你已经封装好了一个类(也可能是系统类、第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类,只需要给你原来的类增加一个分类。
将一个大型的类拆分成不同的分类,在不同分类中实现类别声明的方法,这样可以将一个类的实现写到多个.m文件中,方便管理和协同开发。

@interface 主类类名(分类类名)
//不可以定义成员属性
@end

@implementation 主类类名(分类类名)

@end

扩展是分类的一种特殊形式,通常定义在主类.m文件中,扩展中声明的方法直接在主类.m文件中实现。
分类是不可以声明实例变量,通常是公开的,文件名是:主类名+分类名.h
扩展是可以声明实例变量,是私有的,文件名为:主类名_扩展标识.h,在主类的.m文件中#import该头文件

10.协议,委托

协议文件的创建

  1. 新建文件
  2. 选择iOS平台Source中的Object-C Fie
  3. 选择File Type为protocol,则可建立协议文件

协议文件的特征

  1. 协议文件为单一的.h文件
  2. 命名规则一般为”类名Delegate.h”

使用格式

.h文件中的格式为

#import <Foundation/Foundation.h>

@protocol 类名Delegate <NSObject>

// 在此声明协议方法
// @requires修饰的声明方法,代理方必须实现
// @optional修饰的声明方法,代理方可以不实现

@end

使用方法

委托方将该协议文件导入自己的.h文件中,并添加一个遵守该协议的代理属性

注:就像一般把扩展写在.m文件中,而不单独建立一个扩展文件一样;一般开发中,不单独建立一个协议文件,而是将协议制定在委托方的.h文件中。

相关文章

  • 简述OC基础语法的一些坑洞

    1. 标识符的规则 字母、数字、下划线、美元符$,但是不能以数字开头; 区分大小写 不能是关键字 2. #impo...

  • 技术在于交流,知识在于收集(一)

    收集的一些iOS开发技术博客与牛人共同进步 iOS基础: OC语法基础 OC代码规范 从零学习iOS开发的15条建...

  • 无标题文章

    OC基础语法 //整型 NSIntegera =10; //NSLog是OC里面的打印函数 NSLog(@"a =...

  • SwiftUI 设置TabView的颜色

    前言: 最近看了下SwiftUI一些基础语法,自己写了基本的语法,在写SwiftUI时,不要把OC的思想拿过来用,...

  • MySQL——基本语句

    Mysql-基础语法 导语 本博文主要是简述选择数据库和对表内容的增、删、改和查的一些基本语法 USE 语法: U...

  • iOS培训总结

    一:OC基础语法1 //整型 NSInteger a =10; //NSLog是OC里面的打印函数 NSLog(@...

  • OC之01基础之基础语法

    01 语法概述 不妨将OC说成是面向对象的C语言,因为OC是在C语言的基础是建立的,而且在OC的语法中是完全...

  • OC语法基础

    一、属性与成员变量属性表达实例状态,描述类型对外结果,相比直接访问成员变量,属性可以做更多的控制。默认情况下,编译...

  • OC 语法基础

    OC 的语法知识其实有蛮多,以下知识基础的一部分. 目录部分: @ 符号 在 OC 语言中,绝大部分的关键字使用的...

  • OC:基础语法☀️

    版权声明:本文为博主原创文章,未经博主允许不得转载。 学习目标 1.【了解】Objective-C语言简介 2.【...

网友评论

    本文标题:简述OC基础语法的一些坑洞

    本文链接:https://www.haomeiwen.com/subject/ztbnqftx.html