ios开发ios9新特性关键字学习:泛型,逆变,协变,__kindof

一:如何去学习?都去学习什么?

1:学习优秀项目的设计思想,多问几个为什么,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中 2:学习优秀项目的代码风格,代码的封装设计思想,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中,每行代码都要用心去写,每一行代码都要力求使最简洁的

3:学习别人遇到问题是如何分析问题,解决问题的方法是什么

4:遇到新东西应该如何去学习:1:先研究要学习的东西作用是什么 ,有什么好处  2:如何使用:具体的语法知识 ,参照苹果的API 3:使用场景:一般在项目中有什么应用。

5:最重要的就是花大量的时间研究优秀的代码,比别人想的深比别人想的远,注意每一个细节,把每一个细节都要搞懂,把每一个细节做到极致,花大量的时间去实践练习,将学习到的知识应用于项目中。

 

二:nullable, nonnull,null_resettable,_Null_unspecified 的关键字的认识

/* 1:介绍怎么去研究新特性? 1.使用新的xcode创建项目,用旧的xcode去打开Xcode7 2015 iOS9Xcode6 2014 iOS8Xcode5 2013 iOS7Xcode4 2012 iOS61.出了哪些新特性 iOS9:关键字:可以用于属性,方法返回值和参数中关键字作用:提示作用,告诉开发者属性信息关键字目的:迎合swift,swift是个强语言,swift必须要指定一个对象是否为空关键字好处:提高代码规划,减少沟通成本关键字仅仅是提供警告,并不会报编译错误*//* 2:nullable:nullable:1.怎么使用(语法) 2.什么时候使用(作用)nullable作用:可能为空nullable 语法1@property (nonatomic, strong, nullable) NSString *name;nullable 语法2 * 关键字 变量名@property (nonatomic, strong) NSString * _Nullable name;nullable 语法3@property (nonatomic, strong) NSString * __nullable name;*//* 3:nonnullnonnull:1.怎么使用(语法) 2.什么时候使用(作用)nonnull作用:不能为空nonnull 语法1@property (nonatomic, strong, nullable) NSString *name;nonnull 语法2 * 关键字 变量名@property (nonatomic, strong) NSString * _Nonnull name;nonnull 语法3@property (nonatomic, strong) NSString * __nonnull name;*//*4:null_resettable:null_resettable:1.怎么使用(语法) 2.什么时候使用(作用)null_resettable:必须要处理为nil情况,重写get方法null_resettable作用:get方法不能返回nil,set可以传入为空null_resettable 语法1@property (nonatomic, strong, null_resettable) NSString *name;- (NSString *)name{if (_name == nil) {_name = @"";}return _name;}*//*5:_Null_unspecified:不确定是否为空*//*6:1:关键字注意点在NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之间默认是nonnull,一般前者写在头文件之下,后者写在end之上2:关键字不能用于基本数据类型(int,float),nil只用于对象3: @property (nonatomic) NSString *name;如此写法,默认为strong修饰的*/#import "ViewController.h"@interface ViewController ()// nonnull
// 没有处理为空的情况
@property (nonatomic, strong, nonnull)NSString  *name;@end@implementation ViewController//- (UIView *)view
//{
//    if (_view == nil) {
//        [self loadView];
//        [self viewDidLoad];
//    }
//    return _view
//}- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.
    
}@end

三:泛型

#import "ViewController.h"/*1:泛型介绍泛型:限制类型 为什么要推出泛型?迎合swift泛型作用:1.限制类型 2.提高代码规划,减少沟通成本,一看就知道集合中是什么东西泛型定义用法:类型<限制类型>:NSMutableArray<NSString *> *arr,数组里存放的都是字符串类型2:类的泛型声明:泛型声明:在声明类的时候,在类的后面<泛型名称>:@interface Person<ObjectType> : NSObject泛型仅仅是报警告泛型好处:1.从数组中取出来,可以使用点语法:数组中存放元素的类型为id类型, id是不能使用点语法,但是利用泛型,给其限制类型,则从数组中取出对象后,可以利用点语法2.给数组添加元素,有提示3: 泛型在开发中使用场景:1.用于限制集合类型:(集合类包括NSArray和NSSet,两者用法相同,前者是有序的,而后者却是无序的)为什么集合可以使用泛型?使用泛型,必须要先声明泛型? => 如何声明泛型自定义泛型?什么时候使用泛型?2: 在声明类的时候,不确定某些属性或者方法类型,在使用这个类的时候才确定,就可以采用泛型自定义Person,会一些编程语言(iOS,Java),在声明Person,不确定这个人会什么,在使用Person才知道这个Person会什么语言如果没有定义泛型.默认就是id例如:1;声明泛型#import <Foundation/Foundation.h>@interface Person<ObjectType> : NSObject// 语言@property (nonatomic, strong) ObjectType language;@end2:使用:Java *java = [[Java alloc] init];iOS *ios = [[iOS alloc] init];// iOSPerson<iOS *> *p = [[Person alloc] init];p.language = ios;// JavaPerson<Java *> *p1 = [[Person alloc] init];p1.language = java;*/#import "Person.h"
#import "Java.h"
#import "iOS.h"
@interface ViewController ()@property (nonatomic, strong) NSMutableArray<NSString *> *arr;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];Java *java = [[Java alloc] init];iOS *ios = [[iOS alloc] init];// iOSPerson<iOS *> *p = [[Person alloc] init];p.language = ios;// JavaPerson<Java *> *p1 = [[Person alloc] init];p1.language = java;
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{}@end

四:泛型的协变和逆变

#import "ViewController.h"/*  1:泛型:限制类型 为什么要推出泛型?迎合swift泛型作用:1.限制类型 2.提高代码规划,减少沟通成本,一看就知道集合中是什么东西泛型定义用法:类型<限制类型>泛型声明:在声明类的时候,在类的后面<泛型名称>泛型仅仅是报警告泛型好处:1.从数组中取出来,可以使用点语法2.给数组添加元素,有提示泛型在开发中使用场景:1.用于限制集合类型id是不能使用点语法为什么集合可以使用泛型?使用泛型,必须要先声明泛型? => 如何声明泛型自定义泛型?什么时候使用泛型?在声明类的时候,不确定某些属性或者方法类型,在使用这个类的时候才确定,就可以采用泛型自定义Person,会一些编程语言(iOS,Java),在声明Person,不确定这个人会什么,在使用Person才知道这个Person会什么语言如果没有定义泛型.默认就是id用于父子类型转换泛型:__covariant:协变, 子类转父类 :也就是将子类的指针赋值给子类__contravariant:逆变 父类转子类:也就是将父类的指针赋值给子类泛型注意点:在数组中,一般用可变数组添加方法,泛型才会生效,如果使用不可变数组,添加元素,泛型没有效果,只是提示的作用2:继承:子类继承父类后,父类可在.h中暴露方法例如初始化方法供子类去继承 1:父类只暴露了初始化方法没有重写,子类继承后,子类可以重写,(子类在重写时,尽量用self,不要用类名,避免其他类在继承该类的时候,初始化得到的都是该类的对象,而不是继承的子类的对象。)那么子类重写后,在父类中的self就为子类的对象,其中多个子类继承同一个父类的时候,父类可以提供一个get的标识方法供子类重写返回标识,从而在父类中来区分不同的子类 2:父类提供方法,供子类继承,父类在实现该方法,则子类在外部调用初始化方法的时候,就会调用父类中实现的初始化方法。(新浪参数模型抽父类继承的例子),若是子类又重写父类的初始化方法,调用super会执行父类的方法,否则就不会执行父类的方法,会覆盖掉父类的方法,只保留子类的方法*/#import "Person.h"
#import "Java.h"
#import "iOS.h"
@interface ViewController ()@property (nonatomic, strong) NSMutableArray<NSString *> *arr;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[_arr addObject:@"123"];
//    _arr = @[@"213",@"213",@1];// Do any additional setup after loading the view, typically from a nib.
    iOS *ios = [[iOS alloc] init];Language *language = [[Language alloc] init];// 父类转子类Person<Language *> *p = [[Person alloc] init];p.language = language;// iOSPerson<iOS *> *p1 = [[Person alloc] init];p1 = p;}
// 子类转父类
- (void)covariant
{iOS *ios = [[iOS alloc] init];Language *language = [[Language alloc] init];// iOSPerson<iOS *> *p = [[Person alloc] init];p.language = ios;// LanguagePerson<Language *> *p1;p1 = p;}- (void)test
{Java *java = [[Java alloc] init];iOS *ios = [[iOS alloc] init];// iOSPerson<iOS *> *p = [[Person alloc] init];p.language = ios;// JavaPerson<Java *> *p1 = [[Person alloc] init];p1.language = java;}@end

五:__kindof

#import "ViewController.h"
#import "SubPerson.h"/*kindof:相当于__kindof:表示当前类或者它的子类',类设计历史id:可以调用任何对象方法,可以作为参数或是返回值,不能进行编译检查instancetype:自动识别当前类的对象,只能作为返回值不能作为参数,自动返回与当前类类型相同的对象*/@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];/***    当父类提供初始化的方法的时候,子类继承了父类的方法,若是子类SubPerson调用父类的初始化方法:person,则返回的是父类对象的类型,会出现警告,这时,可以在父类中定义的初始化方法用__kindof来修饰,表示当前类或是其子类。+ (__kindof Person *)person;*/SubPerson *p = [SubPerson person];}@end

 

转载于:https://www.cnblogs.com/cqb-learner/p/5868702.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS高级——模块化学习笔记

一、什么是模块化&#xff1f; 到底什么是模块化、模块化开发呢&#xff1f; 事实上模块化开发最终的目的是将程序划分成一个个小的结构&#xff1b;这个结构中编写属于自己的逻辑代码&#xff0c;有自己的作用域&#xff0c;不会影响到其他的结构&#xff1b;这个结构可以将…

python notebooks_Jupyter Notebooks安装及入门

1.Jupyter Notebooks 是什么&#xff1f;Jupyter Notebooks 是一款开源的网络应用&#xff0c;我们可以将其用于创建和共享代码与文档。其提供了一个环境&#xff0c;你无需离开这个环境&#xff0c;就可以在其中编写你的代码、运行代码、查看输出、可视化数据并查看结果。因此…

JS高级——JSON、数据存储学习笔记

在目前的开发中&#xff0c;JSON是一种非常重要的数据格式&#xff0c;它并不是编程语言&#xff0c;而是一种可以在服务器和客户端之间传输的数据格式。 JSON的全称是JavaScript Object Notation&#xff08;JavaScript对象符号&#xff09;&#xff1a; JSON是由Douglas Cro…

beautifulsoup获取属性_Python爬虫常用模块:BeautifulSoup

BeautifulSoup用途 BeautifulSoup 借助网页的结构和属性等特性来解析网页&#xff0c;可以用它来方便地从网页中提取所需信息。 BeautifulSoup自动将输入文档转换为Unicode编码&#xff0c;输出文档转换为UTF-8编码。BeautifulSoup依赖于解析器 它除了支持Python标准库中的HTML…

CSS3选择器的研究

属性选择器 [title]:选择带有title属性的元素 [titlehello]:选择属性是title并且值是hello的元素 [title~hello]:选择属性是title并且部分值是hello的元素&#xff0c;hello需要是单独的值&#xff0c;以空格分开 [title*hello]:选择属性是title并且其中包含了hello的元素 [tit…

手写实现简单的Vue事件总线

一、什么是事件总线 自定义事件总线属于一种观察者模式&#xff0c;其中包括三个角色&#xff1a; 发布者&#xff08;Publisher&#xff09;&#xff1a;发出事件&#xff08;Event&#xff09;&#xff1b;订阅者&#xff08;Subscriber&#xff09;&#xff1a;订阅事件&a…

dhs手术是什么意思_#下颌角手术# #磨骨瘦脸# 下颌角手术多少钱?

不要一上来就问价格多少钱&#xff0c;有些人就留言说怕我这里手术太贵&#xff0c;前面问一圈其他问题都白问了。还有些人担心手术会因人定价&#xff0c;坐地起价之内的。其他地方我不知道&#xff0c;反正我能确保我这里价格标准都是一致的&#xff0c;下颌角总计30000-3500…

手写实现深拷贝函数

对象相互赋值的一些关系&#xff0c;分别包括&#xff1a; 引入的赋值&#xff1a;指向同一个对象&#xff0c;相互之间会影响&#xff1b;对象的浅拷贝&#xff1a;只是浅层的拷贝&#xff0c;内部引入对象时&#xff0c;依然会相互影响&#xff1b;对象的深拷贝&#xff1a;两…

第一款支持容器和云部署的开源数据库Neo4j 3.0

导读Neo4j 3.0.0 正式发布&#xff0c;这是 Neo4j 3.0 系列的第一个版本。此版本对内部架构进行了全新的设计&#xff1b;提供给开发者更强大的生产力&#xff1b;提供更广阔的部署选择。Neo4j 3.0 被认为是世界上最具伸缩性的基于Java的图片数据库。Neo4j 3.0.0 主要的新特性&…

八皇后解法(回溯法)

package com.company;/** * Created by Administrator on 2016/9/15. */public class EigthQueue { private static int N 8; private int count 0; // 总方案数 private int[] flag {-1, -1, -1, -1, -1, -1, -1, -1}; //回溯法递归实现八皇后问题 //输出棋…

手写防抖和节流函数

一、认识防抖debounce函数 我们用一副图来理解一下它的过程&#xff1a; 当事件触发时&#xff0c;相应的函数并不会立即触发&#xff0c;而是会等待一定的时间&#xff1b;当事件密集触发时&#xff0c;函数的触发会被频繁的推迟&#xff1b;只有等待了一段时间也没有事件触…

中webgl解析json_WebGL蒙皮(下)

今天继续学习webgl一个重要功能&#xff1a;skinning(蒙皮)&#xff0c;内容来自学习网站webglfundamentals&#xff0c;这里仅供学习交流&#xff0c;原文链接&#xff1a;https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-skinning.html。文章并非原创&#xff01;如…

Vue权限控制——动态注册路由

需求&#xff1a;实现后台管理系统不同用户的权限控制 根据登录的用户的角色动态展示后台管理系统的左侧菜单栏的菜单列表内容&#xff0c;然后还要动态注册对应子菜单的路由 菜单列表内容应该通过后端接口返回&#xff1a; sort为1表示当前项有子菜单sort为2表示当前项没有子…

react不同环境不同配置angular_前端问题集:vue配置环境-给不同的环境配不同的打包命令...

通过vue-cli脚手架构建出一个前端项目&#xff0c;通过npm run build打包&#xff0c;发布到线上&#xff0c;但是这样做需要每次都手动修改接口地址。我们可以通过自行配置打包命令实现无需修改接口地址&#xff0c;打各个环境的包。文档结构大致如下图&#xff1a;1.找到conf…

使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序

今天用plsql连接oracle的时候报了无监听程序&#xff0c;寻思是plsql的问题&#xff0c;可惜重装了也没什么卵用&#xff0c;才把注意力集中到oracle服务上&#xff0c;啥也不说了&#xff0c; 直接上链接&#xff1a; 使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序转载…

基于Element-plus封装配置化表单组件(组件的v-model实现)

一、预备知识 1.1 组件的v-model 前面我们在input中可以使用v-model来完成双向绑定&#xff1a; 这个时候往往会非常方便&#xff0c;因为v-model默认帮助我们完成了两件事&#xff1b;v-bind:value的数据绑定 和 input的事件监听&#xff1b; 如果我们现在封装了一个组件…

Scala IDE for Eclipse的下载、安装和WordCount的初步使用(本地模式和集群模式)

不多说&#xff0c;直接上干货&#xff01; 这篇博客是&#xff0c; 是在Scala IDEA for Eclipse里maven创建scala和java代码编写环境。 Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境&#xff08;图文详解&#xff09; 本博文包括&#xff1a; Scala IDE fo…

笔记本AutoCAD启动时闪退怎么办_戴尔笔记本电脑开不了机如何解决【解决方法】...

生活在互联时代下&#xff0c;我们对笔记本的需求是无处不在的&#xff0c;不管是上班族还是学生党&#xff0c;使用笔记本办公和学习给我们的生活带来很大的便捷。但使用的过程中&#xff0c;总有可能会遇到无法预料的问题。比方说 笔记本电脑 无法开机的问题&#xff0c;当…

JS高级——函数执行、作用域链内存结构图

一、JavaScript的执行过程 假如我们有下面一段代码&#xff0c;它在JavaScript中是如何被执行的呢&#xff1f; 1.1 第一步&#xff1a;初始化全局对象 js引擎会在执行代码之前&#xff0c;会在堆内存中创建一个全局对象&#xff1a;Global Object&#xff08;GO&#xff09…

两个队列+k叉哈夫曼树 HDU 5884

1 // 两个队列k叉哈夫曼树 HDU 58842 // camp题解&#xff1a;3 // 题意&#xff1a;nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, 问kk最小是多少。4 // .5 // 题解&#xff1a;首先二分一下这个kk。然后在…