纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

ObjectiveC 入门篇 Objective-C 入门篇(推荐)

会飞的狗~   2021-11-27 我要评论
想了解Objective-C 入门篇(推荐)的相关内容吗会飞的狗~在本文为您仔细讲解ObjectiveC 入门篇的相关知识和一些Code实例欢迎阅读和指正我们先划重点:ObjectiveC 入门篇,Objective-C 入门篇下面大家一起来学习吧

前言

Objective-C is the primary programming language you use when writing software for OS X and iOS. It's a superset of the C programming language and provides object-oriented capabilities and a dynamic runtime. Objective-C inherits the syntax, primitive types, and flow control statements of C and adds syntax for defining classes and methods. It also adds language-level support for object graph management and object literals while providing dynamic typing and binding, deferring many responsibilities until runtime.

Objective-C(下面简称OC)是由C语言和Smalltalk扩展出来的是C语言的超集最大的区别是OC是面向对象的其火星文写法对于之前从事Java开发的同学颇感蛋疼OC最大特点之一是使用“消息结构”而不是“函数调用”所以在运行时执行的代码由运行环境决定而Java是由编译器决定个人感觉有关于IOS学习的文章相较于Android质量较低有可能是苹果系统封闭的原因本文侧重介绍常用的语法通过对比Java并结合本人入门的过程和经验帮助有需求的同学快速掌握OC基本编程为IOS的入门奠定语言基础下面首先是写出第一行代码恭喜正式进入OC学习阶段

int main(int argc, char *argv[])
{
    @autoreleasepool //创建自动内存释放池
    {
    	//打印输出
        NSLog(@"hello world ios!");
        return 0;
    }
}

下面介绍OC代码的文件扩展名:

文件扩展名 类型
.h 头文件作用是对类、属性、变量、函数等的声明
.m 实现文件对头文件的生命实现或者扩展
.mm 实现文件一般是C++代码

如果实现文件需要引入头文件时推荐使用#import跟#include作用相同优化了确保相同文件只会被引入一次所以倾向用#import

基本数据类型

包括:int float double char

类型 字节数 格式化输出
char 1 %c
int 4 %i,%x,%o
unsigned int 4 %i,%x,%o
short int 2 %hi,%hx,%ho
unsigned short int 2 %hi,%hx,%ho
long int 8 %li,%lx,%lo
unsigned long int 8 %lu,%lx,%lo
long long int 8 %lli,%llx,%llo
unsigned long long int 8 %llu,%llx,%llo
float 4 %f
double 8 %f
long double 16 %Lf

其他数据类型

id类型

可以存放任何数据类型的对象类似Java中的Object类其被定义为指向对象的指针(本身就是指针了)故定义比如id instance = nil;id类型是多态和动态绑定的基础

BOOL类型

布尔值为YES/NO或1/0Java对应是true/false

nil和Nil

nil相当于Java中的null表示一个对象这个对象的指针指向空Nil是定义一个指向空的类而不是对象

NSString(不可变字符串)

字符串是非常重要常用的务必要掌握常用的基础用法包括创建、截取、遍历、比较、大小写转换、搜索等语义跟基本类似Java

//字符串
NSString *str1 = @"ABC3456789";
//拼接成新的字符串
 NSString *str2 = [str1 stringByAppendingString:@"wwww"];
NSLog(@"str = %@", str2);
//遍历
for (int i = 0; i < [str2 length]; i++) {
    char temp = [str2 characterAtIndex:i];
    NSLog(@"字符串第 %d 位输出 %c", i, temp);
}
//比较
// sEqualToString方法 :比较字符串是否完全相等大小写不一样也无法完全匹配
//hasPrefixe方法:逐一匹配字符串头部haSuffix方法:匹配字符串的尾部
if ([str2 isEqualToString:str1]) {
    NSLog(@"相等");
}
if ([str2 hasPrefix:@"www"]) {
    NSLog(@"有该头部");
}
if ([str2 hasSuffix:@"www"]) {
    NSLog(@"有该尾部");
}
if ([str2 compare:str options:NSCaseInsensitiveSearch | NSNumericSearch] == NSOrderedSame) {
}
NSLog(@"比较结果:%d", [str2 caseInsensitiveCompare:str1]);
//大小写转换
NSLog(@"str3转大写:%@",[str2 uppercaseString]);
NSLog(@"str3转小写:%@",[str2 lowercaseString]);
NSLog(@"str3首字母转大写:%@",[str2 capitalizedString]);
//字符串截取
NSRange rang = NSMakeRange(2, 2);
NSLog(@"str3截取:%@",[str2 substringWithRange:rang]);
//搜索
NSRange rang1 = [str2 rangeOfString:@"www"];
NSLog(@"location: %d,length: %d",rang1.location,rang1.length);
//替换
//全部替换
NSString *str3 = [str2 stringByReplacingOccurrencesOfString:@" " withString:@"@"];
NSLog(@"替换后字符串为%@", str3);
//局部替换
NSString *str4 = [str2 stringByReplacingCharactersInRange:rang withString:@"met"];
NSLog(@"替换后字符串为%@", str4);

NSMutableString(可变字符串)

创建对象的基本写法是[[NSMutableString alloc]init]*号代表对象[]代表方法调用只能通过类或者对象才能调用[NSMutableString alloc]类似Java中new得到一个对象然后再调用init初始化方法

		//创建对象并初始化
		NSMutableString *mStr = [[NSMutableString alloc]init];
        //appendstring:向字符串尾部添加一个字符串
        //appendFormat:向字符串尾部添加多个类型的字符串可以添加任意数量与类型的字符串
        [mStr appendString:@"hello world!"];
        NSLog(@"字符串创建%@", mStr);
        [mStr deleteCharactersInRange:[mStr rangeOfString:@"hello"]];
        //删除
        NSLog(@"字符串删除%@", mStr);
        //插入
        [mStr insertString:@"love you" atIndex: mStr.length];
        NSLog(@"字符串插入%@", mStr);

NSInteger、NSUInteger和NSNumber

NSInteger不是一个对象而是基本数据类型中的typedefNSUInteger是无符号的 当需要使用int类型的变量时推荐使用NSInteger这样不需要考虑设备是32位或者64位NSNumber是一个类用于包装基本数据类型成为对象可以理解为Java中的装箱为一些集合只能存放对象使用通过字面量方式非常方便将基本数据类型转成对应的对象例如:

//包装
NSNumber *intNumber = [[NSNumber alloc]initWithInt:43];
//或者字面量方式
NSNumber *intNumber1 = @43;
//还原基本数据类型解包
NSLog(@"%d",[intNumber intValue]);

集合

集合不能接受nilnil是作为集合结束标识符

1. NSArray(不可变)

类似Java中的ArrayList可以存储不同类型的对象一般情况下数组元素的类型是相同的特点是有序、可重复下面展示一位数组的基本操作: 

//字面量创建方式
    NSArray *arr2 = @[@"aaa",@"bbbbb"];
//工厂方法创建
    NSArray *array = [[NSArray alloc] initWithObjects:@"1", @"2", nil];
    //取最后一个元素
    [array lastObject];
//    取第一个元素
    [array firstObject];
//    数组是否包含某个元素
    [array containsObject:@"1"];
//    数组的大小
    int count = (int) array.count;
//    第一种方式遍历
    for (int i = 0; i < count; i++) {
        NSString *_str = [array objectAtIndex:i];
    }

那么数据要求是多维的呢?多维数组可以理解为数组的数组通过嵌套的方式创建如下:

// 字面量创建二维数组并访问
NSArray *arr2 = @[@[@11, @12, @13], @[@21, @22, @23], @[@31, @32, @33]];
// 字面量访问方式(推荐)
NSLog(@"arr2[2][2]:%@", arr2[2][2]);
// 数组对象函数访问
NSLog(@"arr2[2][2]:%@", [[arr2 objectAtIndex:2] objectAtIndex:2]);

2. NSMutableArray(可变的)

派生于NSArray理解为动态数组提供增加、删除、插入、替换等语法糖

		//创建当然还有其他方式
        NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil];
        //添加
        [mutableArr addObject:@"hello"];
        //替换
        [mutableArr replaceObjectAtIndex:2 withObject:@"tihuan"];
        //删除
        [mutableArr removeObjectAtIndex:1];
        //插入
        [mutableArr insertObject:@"ios" atIndex:1];

多维数组创建方式如下:

   		// 初始化作为列的数组看做4列
NSMutableArray *columnArray = [[NSMutableArray alloc]initWithCapacity:4];

// 初始化2个一维数组每个一维数组有4个元素看做1行4列2行加起来就是2行4列
NSMutableArray *rowArray1 = [[NSMutableArray alloc]initWithCapacity:4];
NSMutableArray *rowArray2 = [[NSMutableArray alloc]initWithCapacity:4];

// 每个行依次增加数组元素
// 第一行
[rowArray1 addObject:@"11"];
[rowArray1 addObject:@"12"];
[rowArray1 addObject:@"13"];
[rowArray1 addObject:@"14"];

// 第二行
[rowArray2 addObject:@"21"];
[rowArray2 addObject:@"22"];
[rowArray2 addObject:@"23"];
[rowArray2 addObject:@"24"];

// 分别打印数组
NSLog(@"myRowArray1: %@", rowArray1);
NSLog(@"myRowArray2: %@", rowArray2);
NSLog(@"myColumnArray: %@", columnArray);

字典

类似于Java中的HashMap是一种映射型数据结果存储键值对有可变和不可变两种类型

NSDictionary

主要特点是不可变如果集合初始化完成将内容无法修改无序

	//标准创建
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"cat",@"name1",@"dog",@"name2", nil];
    //字面量创建
    NSDictionary *dict1 = @{@"name1":@"cat",@"name2":@"dog"};
	//第一种遍历
    for (NSString *key in [dict1 allKeys]) {
        NSLog(@"key: %@,value: %@", key, dict1[key]);
    }
    //第二种遍历方式通过遍历器
    NSEnumerator *rator = [dict keyEnumerator];
    NSString *temp;
    while (temp = [rator nextObject]) {
        NSLog(@"%@", temp);
    }
    //获取元素
	dict1[@"name"];
	[dict1 objectForKey:@"name"];
	//集合元素的个数
	NSInteger count = dict1.count;
	//沙盒文件存储和读取Plist
	[dict5 writeToFile:@"路径" atomically:YES];
	NSDictionary *dict7 = [NSDictionary dictionaryWithContentsOfFile:@"路径"];

NSMutableDictionary

NSMutableDictionary是NSDictionary的子类NSMutableDictionary是可变的动态添加、更改、删除元素因此不能使用字面量方式(@{})来创建一个可变字典如果是不可变字典出现了同名的key那么后面的key对应的值不会被保存反之是可变字典出现了同名的key那么后面的值会覆盖前面的值

//创建
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
//添加
[dict setObject:@"dog" forKey:@"name"];
[dict setValue:@"18" forKey:@"age"];
//会将传入字典中所有的键值对取出来添加到dict中
[dict setValuesForKeysWithDictionary:@{@"name1":@"dog"}];
//取元素
[dict objectForKey:@"name"];
dict[@"name"];
//删除
[dict removeAllObjects];
[dict removeObjectForKey:@"name"];
[dict removeObjectsForKeys:@[@"name", @"age"]];
//更新如果利用setObject方法给已经存在的key赋值新值会覆盖旧值
[dict setObject:@"20" forKey:@"age"];
dict[@"age"] = @"30";

NSSet && NSMutableSet

具有很好的存取和查找功能与NSArray相比NSSet的元素没有索引特点是无序不可重复类似Java中的HashSet其中NSMutableSet提供计算交并集的方法

NSSet存储元素的过程:

注意:推荐使用字面量方式创建对象可以缩短代码长度增加可读性但是在创建数组的时候要注意如果含有nil就会抛异常因为字面量实际上”语法糖“效果等同于先创建一个数组然后再把所有的对象添加进来保证数组不添加nil

消息传递

前言提到Objective-C最大特点之一是继承了Smalltalk消息传递模型因此在OC中的方法调用准备的说法是消息传递类别与消息关系松散调用方法是给对象发送消息而方法是对消息的回应所有消息的处理直到运行时(即runtime)才会动态确定并交由类自行决定如何处理收到的消息总结是一个类不保证一定会回应收到的消息当收到的一个无法处理的消息会抛出异常

Java或者C++方法调用:

obj.method(argument);

OC方法调用:

[obj method: argument];

我们都知道在Java或者C++中如果类没有定义method方法那么编译肯定不会通过但是在OC中理解是发送method的消息给objobj收到消息后再决定如何回应消息如果类内定义了method方法则运行反之不存在运行期抛出异常

所有面向对象的编程都有类的概念用于封装数据这样的语言特性都有封装、继承和多态OC对象是类在运行期的实例包含了类声明的实例变量、内存拷贝、类成员的指针等由于OC是C语言的超集类由两个部分组成分别是定义(interface)和实现(implementation)下面举个?新建一个People类@interface是接口声明的开始@end终止结束所有的OC编译指令都是以”@“开始的类的实现是通过@implementation指令开头以@end结束对应People.h和People.m两份文件下图是类声明(People.h)的展示主要包括继承关系、成员变量、属性、方法声明等方法的具体实现是在People.m

下图是方法声明的展示:

当然不止Interface区块可以定义变量Implementation区块也可以定义两者区别是访问权限不一

前者默认权限为protected而implementation区块的实体变量则默认为private所以类别私有可以放在implementation区块

访问修饰符

  • @public:任何位置可以访问
  • @protected:默认情况下成员变量的修饰符
  • @private:变量只限于声明它的类访问不允许被继承
  • @package:限定在当前包内类似于Java包的概念

属性

成员变量是给类内使用的属性是作为类外访问成员变量的接口用于封装对象的数据通过@property声明编译器自动生成setter和getter方法此过程称为”自动合成“类实现文件中@synthesize语法可以指定实例变量的名字一般不推荐这样做@dynamic语法是告诉编译器不要自动合成在OC中访问修饰符很少用到主要是靠声明属性取值

属性有五个常用的特质修饰:

assign:针对基本数据类型赋值操作
strong:定义一种”拥有关系“属性设置新值时先保留新值并释放旧值然后再将新值设置
weak:跟strong相反属性所指的对象销毁时属性值也会清空
copy:设置方法不保留新值而是拷贝一份
nonatomic:非原子非线程安全类型

Q&A:为什么NSString 、 NSArray、 NSDictionary的属性要用copy集合的深浅拷贝是怎样的?

copy属性作用是为变量赋值的时候系统自动copy一份内存出来修改新变量不会影响旧变量在Apple规范中NSStringNSArrayNSDictonary推荐使用copy属性而其NSMubtableStringNSMutableArray, NSMutableDictonary属性则使用strong属性

NSString *sourceString = [NSString stringWithFormat:@"hello ios"];
//不产生新的内存空间
NSString *copyStr = [sourceString copy];
//产生新的内存空间
NSMutableString *mutableStr = [sourceString mutableCopy];
NSLog(@"sourceString : %@   %p",sourceString,sourceString);
NSLog(@"copyStr : %@    %p",copyStr,copyStr);
NSLog(@"mutableStr : %@     %p",mutableStr,mutableStr);

使用strong这个属性就有可能指向一个可变对象如果这个可变对象在外部被修改了那么会影响该属性例如:

//代码块   
NSMutableString *string = [NSMutableString stringWithString:@"origin"];//copy
NSString *stringCopy = [string copy];
NSLog(@"string address is: %p",string);
NSLog(@"stringCopy address is: %p",stringCopy);

结果:内存地址不同

NSMutableString *string = [NSMutableString stringWithString:@"origin"];
//NSString *stringCopy = [string copy];
NSString *stringCopy = string;
[string appendString:@"change"];
NSLog(@"string address is: %p",string);
NSLog(@"stringCopy address is: %p",stringCopy);

结果:内存地址相同

结论:

可变对象指向不可变对象会导致不可变对象的值被篡改所以需要copy属性用@property声明NSString、NSArray、NSDictionary 经常使用copy关键字是因为他们有对应的可变类型NSMutableString、NSMutableArray、NSMutableDictionary彼此之间可能进行赋值操作为了不可变对象中的内容不会被无意间变动应该在设置新属性值时拷贝一份

浅拷贝:

在Java中浅拷贝如果是基本数据则拷贝的是基本数据的值;如果是对象则拷贝的是内存地址修改该对象会影响另外一个对象在OC中是对指针的拷贝拷贝后的指针和原本对象的指针指向同一块内存地址故同样会相互影响

深拷贝:

OC中不仅拷贝指针而且拷贝指针指向的内容指针指向不同的内存地址故修改不会相互影响原本对象

非集合类对象中:对immutable对象进行copy操作是指针复制(浅拷贝)mutableCopy操作时内容复制;对mutable对象进行copy和mutableCopy都是内容复制(深拷贝)

方法

通过”+“、”-“分别声明类方法和实例方法方法如果带有多个参数参数在方法名之后接冒号定义多个参数由空格隔开如果参数个数可变使用逗号接省略号例如:

//无参数
- (void)print;
//有参数
- (void)print:(int)a andB:(int)b;

构造方法

第一种是重写init方法第二种是自定义

/**
 重写初始化方法
 **/
- (instancetype)init
{
    self = [super init];
    if (self) {
        _peopleName = @"hello ios";
    }
    return self;
}

/**
 自定义初始化方法
 **/
- (instancetype)initWithNameAndAge:(NSString *)name andAge:(int)age
{
    self = [super init];
    if (self) {
        _peopleName = name;
        _peopleAge = age;
    }
    return self;
}

创建类对象

所有对象和类的引用都是通过指针实现严格地说指针就是一个地址是一个常量而指针变量可以被赋值不同的指针值创建的对象就是一个指针变量通过[People alloc]创建一个People对象分配了内存init是初始化对象构造方法有两种方式第一种是重写init方法第二种是自定义

People *p1 = [[People alloc] init];
//调用自定义的构造方法
People *p3 = [[People alloc] initWithNameAndAge:@"mingzi" andAge:12];
//调用方法
[p3 print];

在OC 2.0中如果创建的对象不需要参数可以直接使用new:

People *p1 = [People new];

self

作为OC的一个关键字代表当前类的对象类似Java中的this最大的作用是让类中的一个方法调用该类另外一个方法或者成员变量可以理解”当前类谁调用了这个方法self就代表谁“

继承

同Java一样只能单继承只允许最多有一个直接父类例如:定义一个父类Computer和子类MacBook注意方法重写类似Java子类要重写父类方法不需要重新声明重写方法在实现部分直接重写目标方法即可如果需要子类调用父类的方法可以通过super关键字调用

//Computer.h文件
#import <Foundation/Foundation.h>
@interface Computer : NSObject
@property(nonatomic,strong)NSString *name;
-(void)calculate;
@end

//  Computer.m
#import "Computer.h"
@implementation Computer
@synthesize name;
-(void) calculate{
    NSLog(@"i can calculate");
}
@end

//  MacBook.h
#import "Computer.h"
@interface MacBook : Computer
@end

//  MacBook.m
#import "MacBook.h"
@implementation MacBook
@end

//main.m
int main(int argc, char *argv[])
{
    @autoreleasepool
    {
        MacBook *macBook = [[MacBook alloc] init];
        macBook.name = @"mac";
        [macBook calculate];
    }
}

多态

封装、继承和多态是面向对象编程语言的三大特性OC的多态是不同对象对同一消息的不同响应方式实际过程主要分为三种:

  • 继承
  • 重写
  • 指向子类的指针指向父类

可以看出跟Java的多态类似理解起来应该比较容易注意是没有方法重载的在OC中不允许

Runtime

实例:用Runtime新增一个类Person, person有name属性有sayHi方法

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import <objc/runtime.h>
#import <objc/message.h>
void sayHi(id self, IMP _cmd, id some)
{
    //self指的是调用该方法传过来的类
    NSLog(@"%@说:%@我%@岁", [self valueForKey:@"name"], some, object_getIvar(self, class_getInstanceVariable([self class], "_age")));
}

int main(int argc, char *argv[])
{
    @autoreleasepool
    {
        //该方法动态创建一个类arg1:继承自哪个类 arg2:新建类的名称 arg3:extraBytes
        Class Person = objc_allocateClassPair([NSObject class], "Person", 0);
        //添加两个实例变量name和agearg2:变量名称arg3:内存地址大小arg5:变量类型
        class_addIvar(Person, "_name", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
        class_addIvar(Person, "_age", sizeof(int), sizeof(int), @encode(int));
        //注册方法名
        SEL s = sel_registerName("say:");
        //arg3:IMP是“implementation”的缩写这个函数指针决定了最终执行哪段代码
        //arg4:方法的参数及返回值
        class_addMethod(Person, s, (IMP)sayHi, "v@:@");
        //通过该类创建一个实体的对象
        id peopleInstance = [[Person alloc]init];
        //给对象的 name 实例变量赋值下面是第二种赋值方式
        [peopleInstance setValue:@"XQM" forKey:@"name"];
        //Ivar nameIvar = class_getInstanceVariable(Person, "_name");
        //object_setIvar(peopleInstance, nameIvar, @"XQM");
        //获取实例变量
        Ivar ageIvar = class_getInstanceVariable(Person, "_age");
        //为变量赋值
        object_setIvar(peopleInstance, ageIvar, @21);
        //调用sayHi方法arg2:注册指定的方法;arg3:带上有一个字符串的参数
        ((void(*)(id, SEL, id))objc_msgSend)(peopleInstance, s, @"大家好");
        //调用完成,将对象置为空
        peopleInstance = nil;
        //通过 objc 销毁类销毁的是一个类不是对象
        objc_disposeClassPair(Person);
    }
}

主要流程是:

定义类的方法->objc_allocateClassPair创建类->class_addIvar给类添加成员变量->sel_registerName注册方法名->class_addMethod给类添加定义的方法->注册该类->创建类对象->class_getInstanceVariable获取成员变量并通过object_setIvar赋值->objc_msgSend调用方法->释放对象销毁类

Category(类别)

Objective-C借用并扩展了Smalltalk实现中的"分类"概念用以帮助达到分解代码的目的类别主要特点是不能增加属性或者成员变量、增加类功能和分离类实现举个例子: 在UIImageView增加了图片异步加载的功能

@interface UIImageView (ImageViewLoader) <AysncImageDownloaderDelegate>
- (void)setOnlineImage:(NSString *)url placeholderImage:(UIImage *)image withRow:(NSNumber *)row;
@end

@implementation UIImageView (ImageViewLoader)

- (void)setOnlineImage:(NSString *)url placeholderImage:(UIImage *)image withRow:(NSNumber *)row;
{
    self.image = image;
    AsyncImageDownLoader *downloader = [AsyncImageDownLoader sharedImageDownloader];
    [downloader startWithUrl:url delegate:self withRow:row];
}
@end

Extension(拓展)

拓展也经常用到主要特点是增加ivar、用于接口分离等例如:ViewController的实现文件增加@interface ViewController ()支持定义属性等

@interface ViewController ()
@property (nonatomic, copy) block b;
@end

@implementation ViewController
@end

异常处理

OC的异常处理极其类似Java中的包括4个指示符分别是@try、@catch、@throw、@finally可能存在异常的代码写在@try块异常处理逻辑写在@catch@finally块的代码总是要执行的@throw作用是抛出异常

协议

类似Java中的接口(interface)类似多重继承功能支持协议继承协议通过定义一系列方法然后由遵从协议的类实现这些方法协议方法可以用@optional关键字标记为可选@required关键字标记为必选编译器会出现检查警告一般来说还是可以编译通过下面看下语法:

@protocol ClickDelegate
- (void)click;
- (void)unclick;
@end

协议最常应用在委托分为委托方和代理方委托方负责定义协议、通过id类型持有协议和调用协议的方法而代理方则遵从协议、设置协议代理对象以及实现协议方法即可

block

类似Java中的Lambda表达式比较复杂笔者的理解还未达到一定解说程度所以这里先不做解释放到后续的文章中介绍

内存管理

Java的内存管理是由垃圾回收器负责OC中引入自动引用计数(ARC)内存管理交由编译器决定引用计数是每个对象都有一个计数器如果对象继续存活计数器递增其引用计数用完之后递减引用计数如果计数变为0表示对象可以被释放了NSObject协议声明了Retain、release和autorelease方法用于操作计数器分别是递增、递减、自动释放操作所有的对象都是收集器的工作对象

ARC:自动引用计数编译器自动生成retain/release
MRC:手动管理引用计数旧版本使用
autoreleasepool:延迟自动释放

strong/weak/assgin最佳实践

基本类型:assgin;
delegate->week;
集合和block用copy;
其他用strong;
block中的self用weak打破循环引用

参考资料

https://www.jianshu.com/p/eb713b1f22dc
https://www.jianshu.com/p/6ebda3cd8052
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html


相关文章

猜您喜欢

  • QT自定义对话框 C/C++ QT实现自定义对话框的代码实例

    想了解C/C++ QT实现自定义对话框的代码实例的相关内容吗lyshark在本文为您仔细讲解QT自定义对话框的相关知识和一些Code实例欢迎阅读和指正我们先划重点: QT自定义对话框, QT对话框下面大家一起来学习吧..
  • Flask  请求钩子 Flask  请求钩子的实现

    想了解Flask  请求钩子的实现的相关内容吗tigeriaf在本文为您仔细讲解Flask  请求钩子的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Flask  请求钩子实现,Flask  请求钩子,请求钩子下面大家一起来学习吧..

网友评论

Copyright 2020 www.eleasoftware.com 【绿软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式