当前位置: 首页 > 科技观察

从C#到Object C转型开发:分析两者之间的差异

时间:2023-03-15 10:47:31 科技观察

C#到ObjectC的转化开发:浅析两者的差异我们希望给大家带来更好更真实的转化过程体验。在上一篇《从C#到Object C,循序渐进学习苹果开发(1)--准备开发账号和开发环境》介绍了一些基本的转换见解和一些基本的准备工作,ObjectC和C#的区别还没有正式真正的介绍过。我们知道,从一种环境或一种语言转换到另一种环境,我们会做一些比较和理解,这样我们就可以很容易地把头脑中的知识联系起来。在这个一切都越来越统一的背景下,我们认为所有的语言特性都是相通的。一、面向对象类1)类定义ObjectC(以下简称OC)和C#都是面向对象的语言。OC虽然比C#更早,起源于C,但是很多特性都非常接近C#。在C#3.0中引入的扩展方法在OC中同样存在。OC和C#都是一样的。它们的继承关系是单继承,不像C++的多继承那么复杂。OC的一个特点要求就是将接口和实现完全分离。对于熟悉C#开发的人来说,这是必须的。转换后的思路是在OC中写一个类,先写接口定义,再写实现。它的语法与C#有很大不同,但也很容易理解。OC的关键字一般都标有@符号,这与C#默认的保留关键字不同。一般可以看到@interface、@property、@keywords。在最新版本的XCode中,它们真的被发挥到了极致。它含有大量的语法糖,与C#基本相同。这一点会在对象的初始化中介绍。OC类定义放在.h文件中,实现放在.m文件中,如下图是类的接口声明。@interfaceSimpleClass:NSObject@end类的实现如下。#import"SimpleClass.h"@implementationSimpleClass@end以上只是一个演示类的概念。一般来说,类都有属性或者方法,所以需要加很多东西。另外,对比OC和C#,没有命名空间的概念。为了避免混淆,OC类一般都用前缀来区分。比如你看到的IOS基础类库中,NS、UI、CA等很多前缀都是这个原因。2)方法的定义如下接口声明了一个方法,方法的定义@interfaceXYZPerson:NSObject-(void)sayHello;@end我们看到上面的方法定义(接口定义)很简单,这里有一个-符号,是用来标识实例方法的,还有一个类级别的方法,用+符号标示.这个加号类似于C#语言中的static关键字。默认情况下,方法中定义为-的实例方法类似于C#中的公共方法。这个(void)定义是返回值的标识符。C#不需要void标识符的括号并且没有返回值。该方法需要在末尾用括号标识。-(无效)打招呼;这个方法的定义是没有参数的,所以这样写。如果方法有多个参数,这个OC就很有意思了。我觉得这是O??C最有个性的地方。如果方法如下:-(void)setCaption:(NSString*)input;类方法的调用是通过空格调用的,而C#是通过点调用的,这也是不一样的。OC在[]中用空格引用,如下。[对象方法];[objectmethodWithInput:输入];刚才定义的sayHello方法可以这样调用[selfsetCaption:@"DefaultCaption"];如果方法定义为多参数(也叫多参数),则定义如下。-(void)setNumerator:(int)nandDenominator:(int)d;然后方法调用就很有意思了。[frac2setNumerator:1andDenominator:5];如果参数比较多,那就一直用这种累加的方式,有点贴近阅读习惯,呵呵。3)参数的定义说完方法的定义和使用,接下来介绍类中属性的定义。我们知道C#中属性的定义很简单,比如publicstringName{get;set;}回头看看OC是怎么定义属性的,一般在.h的接口定义中,可以这样定义。@propertyNSString*名字;@propertyNSString*姓氏;然后在实现类代码中,添加其对应的代码@synthesize关键字@synthesizefirstName,lastName;当然也可以将该属性指定为只读,如下代码所示@property(readonly)NSString*fullName;另外,我们还需要明确一点,该属性默认是线程安全的,即atomic,并且是强类型Strong。@interfaceXYZObject:NSObject@propertyNSObject*implicitAtomicObject;//atomicbydefault@property(atomic)NSObject*explicitAtomicObject;//显式标记为atomic@end很多地方我们在使用properties的时候不需要指定它的线程安全特性,因为它效率更高,一般属性定义代码如下。@property(strong,nonatomic)IBOutletUILabel*lblName;@property(strong,nonatomic)IBOutletUITextField*txtInput;至于是不是所有的属性都要指定为Strong,这个肯定不行,另外一种strong就是weak,就是表示weak类型,strong类型和weak类型主要是针对ARC的,是引用计数的范畴,而Strong是相当于原来的保留。一般来说,为了避免一些强类型对象属性引起的相互引用问题,在代理类和数据源对象中,有一些对象属性如UITable,它们的属性定义必须指定为weak。#p#2。C#中的对象类型和初始化工作,我们知道它包含一些基本类型(Primitive类型)和一些封装的对象类型,比如它的基本类型包括stringintcharfloatlongdoubledecimal等,它对应的封装类型是StringInt32CharSingleInt64DoubleDecimal等等。在OC中,也存在同样的情况。OC的基本类型继承自C语言的基本类型,包括intfloatdoublechar等基本类型,也有很多NS开头的引用类型(或包装类型),如NSStringNSNumberNSDateNSData、NSValue等.,还有很多集合类型NSArray,NSMutableArray,NSDictionary等需要添加引用类型的对象。另外,类似于C#的Object对象或者动态关键字dynamic指定的类型,OC中包含一个id类型,它是一个不确定的类型,可以看成是任意类型的弱定义。id类型是一种独特的数据类型,概念上类似于java的Object类,可以转换为任何数据类型。也就是说,id类型变量可以存储任何数据类型的对象。在内部,这个类型被定义为一个指向对象的指针,实际上是一个指向这种对象的实例变量的指针。需要注意的是,id是一个指针,所以使用id时不需要加星号;例如:idfoo=nil;1)我们知道OC中很多对象都是通过allocinit初始化的,如下代码所示。XYZObject*object=[[XYZObjectalloc]init];在C#中,大多使用new方法进行初始化。其实在OC中也可以通过new方法进行初始化,但只能在默认构造函数中进行。下面的代码等同于上面的语句。XYZObject*object=[XYZObjectnew];但是好像很多人都习惯用第一种方式初始化对象。2)String初始化相信很多人在使用OC的时候,最先让我印象最深的可能就是NSString这个类。这有点类似于C#的String。它们都是固定的字符串对象。如果需要改变类型对于字符串对象,在C#中可以使用StringBuilder,在OC中可以使用NSMutalbeString。NSMutableString就像一个字符串链表。它可以在字符串中动态添加字符串,删除字符串,在指定位置插入字符串,并用它来操作。字符串更灵活。字符串的定义和初始化很简单,我们可以通过下面的方式进行初始化。NSString*someString=@"你好,世界!";我们知道C#也可以使用@字符进行赋值,虽然一般是在多行的情况下使用,但是在OC中,这个@字符是不能省略的。其他数据类型的许多初始化都依赖于@字符。这个@字符可以说是非常强大,也可以说是一个很好的语法糖。例如初始化各种类型的代码如下(在OC中,NSNumber可以放置任何引用类型)NSNumber*myBOOL=@YES;NSNumber*myFloat=@3.14f;NSNumber*myInt=@42;NSNumber*myLong=@42L;NSNumber类型可以容纳各种类型,也可以转换为其他对应的类型,如下代码所示intscalarMagic=[magicNumberintValue];unsignedintscalarUnsigned=[unsignedNumberunsignedIntValue];longscalarLong=[longNumberlongValue];BOOLscalarBool=[boolNumberboolValue];floatscalarSimpleFloat=[simpleFloatfloatValue];doublescalarBetterDouble=[betterDoubledoubleValue];charscalarChar=[someCharcharValue];另外,由于OC引入了id类型,可以认为其功能等同于C#3.0引入的dynamic类型。它可以在运行时判断一个对象是否有某个方法,而不会在编译时强制执行。如果以下代码编译通过,运行时可能会出错。idsomeObject=@"你好,世界!";[someObjectremoveAllObjects];之所以在编译时不检查其对象是否有removeAllObject接口方法,是因为这里的someObject指定为id的动态类型,所以编译器不会检查它的方法。3)对象集合的初始化刚才介绍了字符串等各种类型的初始化。他们中的许多人使用强大的关键字@进行初始化。这种语法糖减少了许多繁琐的方法调用,尤其是对于集合初始化。如果按照传统的集合定义方式,一般是通过下面的方法。NSArray*someArray=[NSArrayarrayWithObjects:someObject,someString,someNumber,someValue,nil];在collection里面,最后必须加一个nil。这不是必须在C#字段中添加这样的标志。在ObjectC里面,如果要通过arrayWithObjects方法构造,就必须加一个这样的东西,告诉它这是最后一个。如果把这个放在第二位,那么构造出来的集合就只有两个对象了,很奇怪。如果使用强大的@method结构,一切都和C#差不多,到这里只能佩服它的神奇了。NSArray*someArray=@[firstObject,secondObject,thirdObject];定义一个字符串集合如下。NSArray*unsortedStrings=@[@"gammaString",@"alphaString",@"betaString"];在C#中,我们经常使用字典对象,非常方便。当然在OC里面,肯定是有这个东西的,毕竟很多语言都会支持的。这个字典类型也是一个集合类型,它的传统构造方法如下",someValue,@"aValue",零];看起来很奇怪,添加指针是按照object和key的方法添加的,这和我们使用C#的习惯很不一样,最后带来了nil的尾巴。如果您使用@constructor函数,一切都会再次干净。已经以key和value的方式存储了,没有使用nil。如果添加nil,则会发生错误。NSDictionary*dictionary=@{@"anObject":someObject,@"helloString":@"Hello,World!",@"magicNumber":@42,@"aValue":someValue};在集合中,如果取一个对象,则通过以下方法获取NSNumber*storedNumber=[dictionaryobjectForKey:@"magicNumber"];也可以通过下标括号获取NSNumber*storedNumber=dictionary[@"magicNumber"];如果是一般的数组集合,可以通过下面的方式获取,和c#很像。NSNumber*storedNumber=array[0];由于时间和空间的问题,我们以后会继续介绍OC相对于C#的各种特点。OC还涉及到很多相关特性,比如扩展方法、协议(类似接口)、代码块等,还有XCode的各种使用特性,有时间会继续介绍。原文链接:https://img.ydisp.cn/news/20220914/vin1eahxc03.html