• 从C#到Objective-C


    Objective-C 程序设计语言采用特定的语法,来定义类和方法、调用对象的方法、动态地扩展类,以及创建编程接口,来解决具体问题。Objective-C 作为 C 程序设计语言的超集,支持与 C 相同的基本语法。有C#语言的编程经验,那么Objective-C将更容易上手,本文将从各个方面对比C#与Objective-C的语法。

    字符串

    声明:

    C#:
    string name = “lwme.cnblogs.com”;
    
    Objective-C:
    NSString *name = @”lwme.cnblogs.com”;

    字符串前面的@符号是objc在标准C语言基础上添加的特性,"SteveZ"前面有一个@符号表示字符串应该作为Cocoa的NSString来处理,是把C string转换成NSString的一个简写。

    获取长度:

    C#:
    name.Length
    
    Objective-C:
    [name length]
    name.length

    转换:

    C#:
    int i = 10;
    string age = i.ToString();
    int intAge = int.Parse(age);
    
    Objective-C:
    NSInteger i = 10;
    NSString *age = [@(i) stringValue]; // 转换成NSNumber再获取字符串值
    NSString *age = [NSString stringWithFormat:@"%d", i];
    NSInteger intAge = [age integerValue];

    拼接:

    C#:
    string host = "lwme" + ".cnblogs.com";
    
    Objective-C:
    NSString *host = @"lwme" @".cnblogs.com"
    NSString *host = [@"lwme" stringByAppendingString:@".cnblogs.com"];
    NSString *host = [NSString stringWithFormat:@"%@%@", @"lwme", @".cnblogs.com"];

    比较:

    C#:
    bool isEqual = strA == strB;
    bool isEqual = string.Compare(strA, strB,  true) == 0; // 忽略大小写
    bool isEqual = string.Compare(strA, strB,  StringComparison.InvariantCultureIgnoreCase) == 0;
    bool isStartWith = strA.StartsWith(strB);
    bool isStartWith = strA.StartsWith(strB, StringComparison.InvariantCultureIgnoreCase);
    bool isEndWith = strA.EndsWith(strB);
    bool isEndWith = strA.EndsWith(strB, StringComparison.InvariantCultureIgnoreCase);
    bool isContain = strA.Contains(strB);
    bool isContain = strA.Contains(strB, StringComparison.InvariantCultureIgnoreCase);
    
    Objective-C:
    BOOL isEqual = [strA isEqualToString: strB];
    BOOL isEqual = [strA caseInsensitiveCompare:strB] == NSOrderedSame; // 忽略大小写
    BOOL isEqual = [strA compare:strB options:NSCaseInsensitiveSearch] == NSOrderedSame;
    BOOL isStartWith = [strA hasPrefix:strB];
    BOOL isEndWith = [strA hasSuffix:strB];
    BOOL isContain = [strA rangeOfString:strB].location != NSNotFound;
    BOOL isContain = [strA rangeOfString:strB options:NSCaseInsensitiveSearch].location != NSNotFound;

    检查是否为空:

    C#:
    bool empty = string.IsNullOrEmpty(value);
    bool empty = string.IsNullOrWhiteSpace(value);
    
    Objective-C:
    BOOL empty = (value == nil || value.length == 0);
    BOOL empty = (value == nil || value.length == 0 || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0);  //  同IsNullOrWhiteSpace

    转换大小写:

    C#:
    string name = value.ToLower();
    string name = value.ToUpper();
    
    Objective-C:
    NSString *name = [value lowercasestring];
    NSString *name = [value uppercasestring];

    格式化:

    C#:
    float x = 2.43534f;
    string s = x.ToString(“n2″);
    string s = string.Format("{0} {1}", "lwme", "cnblogs");
    
    Objective-C:
    float x = 2.34454f;
    NSString *s = [NSString stringWithFormat: @"%.2f", x];
    NSString *s = [NSString stringWithFormat: @"%@ %@", @"lwme", @"cnblogs"];

    可变字符串

    objc和C#一样,字符串都是不可变的,要改变字符串则分别需要使用StringBuilder、NSMutableString。

    C#:
    StringBuilder builder = new StringBuilder(20);
    builder.Append("lwme");
    builder.AppendFormat(".{0}.{1}", "cnblogs", "com");
    
    Objective-C:
    NSMutableString *builder = [NSMutableString stringWithCapacity:20];
    [builder appendString:@"lwme"];
    [builder appendFormat:@".%@.%@", @"cnblogs", @"com"];

    数组

    声明:

    C#:
    string[] data = {};
    string[] data = {"one", "two"};
    
    Objective-C: 
    // 旧语法
    NSArray* data = [NSArray arrayWithObjects:@"one", @"two", nil]; // (定义数组时用逗号分隔对象列表,并且必须以nil结尾)
    // objc 2.0新语法
    NSArray *data = @[]; //空数组
    NSArray* data = @[@"one", @"two"];

    获取长度:

    C#:
    data.Length
    
    Objective-C:
    [data count]
    data.count

    获取/设置元素值:

    C#:
    data[0]
    data[0]="two";
    
    Objective-C:
    [data objectAtIndex:0]
    data[0] // objc 2.0 新语法
    data[0]=@"two";

    查找元素:

    C#:
    int index = data.IndexOf("one");
    
    Objective-C:
    int index = [data indexOfObject:@"one"];

    遍历:

    C#:
    foreach (string item in array) ...
    
    Objective-C:
    for (NSString *item in array) ...

    可变数组

    objc和C#一样,数组是不可变的,如果需要改变数组的元素,则分别要用到List<T>、NSMutableArray。

    C#:
    List<string> list = new List<string>();
    List<string> list = new List<string>(20);
    List<string> list = new List<string> { "lwme", "cnblogs" };
    list.Add("lwme");
    list.AddRange(new[] { "l", "w", "m", "e" });
    list.Insert(0, "lwme");
    list.Remove("lwme");
    list.RemoveAt(0);
    list.Clear();
    bool isContain = list.Contains("lwme");
    bool isContain = list.Contains("lwme", StringComparer.InvariantCultureIgnoreCase);
    
    Objective-C:
    NSMutableArray *list = [NSMutableArray array];
    NSMutableArray *list = [NSMutableArray arrayWithCapcity: 20];
    NSMutableArray *list = [@[@"lwme", @"cnblogs"] mutableCopy];
    [list addObject:@"lwme"];
    [list addObjectsFromArray:@[@"lwme, @"cnblogs"]];
    [list insertObject:@"lwme", atIndex:0];
    [list removeObject:@"lwme"];
    [list removeObjectAtIndex:0];
    [list removeAllObjects];
    BOOL isContain = [list containsObject:@"lwme"];

    字典

    在objc中有不可变的字典NSDictionary,在C#中没有对应的,而可变的字典NSMutableDictionary对应C#中的Dictionary<TKey,TValue>。

    C#:
    Dictionary<string, string> dict = new Dictionary<string, string>();
    Dictionary<string, string> dict = new Dictionary<string, string>(20);
    Dictionary<string, string> dict = new Dictionary<string, string> { {"name", "lwme"}, {"host", "cnblogs"} };
    dict.Add("name", "lwme");
    dict["name"] = "lwme";
    dict.Remove("name");
    dict.Clear();
    dict.ContainsKey("name");
    string name = dict["name"]; // dict.TryGetValue("name", out ...)
    
    Objective-C:
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: @"lwme", @"name", @"cnblogs", @"host", nil]; // 旧语法
    NSDictionary *dict = @{@"name": @"lwme", @"host": @"cnblogs"}; // objc2.0语法
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 20];
    NSMutableDictionary *dict = [@{@"name": @"lwme", @"host": @"cnblogs"} mutableCopy];
    [dict setObject:@"lwme" forKey:@"name"];
    [dict removeObjectForKey:@"name"];
    [dict removeAllObjects];
    BOOL isContain = [[dict allKeys] containsObject:@"name"];
    BOOL isContain = [dict objectForKey:@"name"] != nil;
    NSString *name = [dict objectForKey:@"name"];
    NSString *name = dict[@"name"];

    各种数值

    objc中有c语言的基本类型如int、float、struct等,还有它们的封装类型NSNumber,由于NSArray、NSDictionary只能存储对象,不能存储任何基本类型,所以这些基本类型需要用NSNumber来包装。

    C#:
    int ii = 1;
    long li = 1;
    float fi = 1.1;
    double di = 1.1;
    bool b = true;
    
    Objective-C:
    int ii = 1;
    long li = 1;
    float fi = 1.1;
    double di = 1.1;
    bool b = true;
    BOOL b = YES;
    NSNumber ii = [NSNumber numberWithInt: 1];
    NSNumber li = [NSNumber numberWithLong: 1];
    NSNumber fi = [NSNumber numberWithFloat: 1.1];
    NSNumber di = [NSNumber numberWithDouble: 1.1];
    NSNumber b = [NSNumber numberWithBOOL: YES];
    NSNumber ii = @1;
    NSNumber li = @1;
    NSNumber fi = @1.1;
    NSNumber di = @1.1;
    NSNumber b = @YES;

    类、属性、方法

    objc的类分成.h头文件和.m实现文件,.h头文件里定义所有公开的方法、属性、字段,.m实现文件里实现公开的方法以及私有的字段、方法。

    C#: 
    public class Person
    {
      private int privateField;
      public int Age {get;set;}
      public string FirstName {get;set;}
      public string LastName {get;set;}
      
      public Person(int age) {
        this.Age = age;
        this.OnAgeChange(age);
      }
      
      private void OnAgeChange(int age) {
      
      }
      
      public string GetFullName() {
        return this.FirstName + " " + this.LastName;
      }
      
      public void SetFullName(string firstName, string lastName) {
        this.FirstName = firstName;
        this.LastName = lastName;
      }
      
      public virtual void PrintAge(){
        Console.WriteLine("{0}", this.Age);
      }
      
      public static Person CreatePerson(int age) {
        return new Person(age);
      }
    }
    
    Objective-C: 
    Person.h:
    @interface Person : NSObject
    -(id)initWithAge:(int)age; // 构造器
    @property(nonatomic) int age; // 属性
    @property(nonatomic) NSString *firstName;
    @property(nonatomic) NSString *lastName;
    -(NSString*)getFullName; // 方法
    -(void)setFullName:(NSString *)firstName andLastName:(NSString *)lastName;
    -(void)printAge;
    +(id)createPersonWithAge:(int)age;
    @end
    
    Person.m:
    @interface Person()
    {
       int _privateField; // 私有字段
    }
    @end 
    
    @implementation Person
    
    @synthesize age, firstName, lastName;
    
    -(id)initWithAge:(int)age 
    {
       if(self = [super init])
       {
          self.age = age;
          [self onAgeChange:age];
       }
       return self;
    }
    -(void)onAgeChange:(int)age
    {
    
    }
    -(NSString*)getFullName
    {
       return [NSString stringWithFormat:"%@ %@", self.firstName, self.lastName]; 
    }
    -(void)setFullName:(NSString *)firstName andLastName:(NSString *)lastName
    {
       self.firstName = firstName;
       self.lastName = lastName;
    }
    -(void)printAge
    {
       NSLog(@"%i", self.age);
    }
    +(id)createPersonWithAge:(int)age
    {
       return [[Person alloc] initWithAge:age];
    }
    @end

    访问对象属性:

    C#: 
    Person p = new Person(11);
    Person p = Person.CreatePerson(11);
    p.setFullName("lwme", "cnblogs");
    p.FirstName = "lwme";
    p.PrintAge();
    string fullName = p.GetFullName();
    int age = p.Age;
    
    Objective-C: 
    Person *p = [[Person alloc] initWithAge:11];
    Person *p = [Person CreateWithAge:11];
    [p setFullName:@"lwme" andLastName:@"cnblogs"];
    p.firstName = @"lwme";
    [p PrintAge];
    NSString *fullName = [p getFullName];
    int age = p.Age;

    继承及调用父类方法:

    C#: 
    public class ChildPerson: Person
    {
      public ChildPerson(int age): base(age){}
      
      public override void PrintAge() {
        base.PrintAge();
        Console.WriteLine("print age in childperson");
      }
    }
    
    Objective-C: 
    ChildPerson.h
    @interface ChildPerson:Person
    @end
    
    ChildPerson.m
    @interface ChildPerson()
    @end
    
    @implementation ChildPerson
    -(void)printAge
    {
      [super printAge];
      NSLog(@"print age in childperson");
    }
    @end

    获取描述信息:

    C#: 
    ChildPerson p = new ChildPerson(11);
    string val = p.ToString();
    
    Objective-C: 
    ChildPerson *p = [[ChildPerson alloc] initWithAge:11];
    NSString *val = [p description];

    接口及事件

    objc中的协议可以对应C#中的接口、事件,其中事件一般声明为delegate名称的属性,在使用的时候只需要设置delete就可以绑定所有事件。

    声明及实现:

    C#
    public interface IEquatable<T>
    {
      bool Equals(T obj);
    }
    
    public class Person : IEquatable<MyClass>
    {
      public Action<Person> onAgeChanged;
    
      public int Age { get; set; }
      
      public bool Equals(Person p)
      {
        return p.Age == this.Age;
      }
      
      public void SetAge(int age) {
        this.Age = age;
        if (onAgeChanged != null)
          onAgeChanged(this);
      }
    }
    
    Objective-C
    @protocol IEquatable
    @required
      -(bool)equals: (Person*)obj;
    @end
    
    @protocol IChangeAction
    @optional
      -(void)onAgeChange: (Person*)obj;
    @end
    
    @interface Person : NSObject<IEquatable>
    @property(nonatomic) int age;
    @property(nonatomic, weak)id<IChangeAction> delegate;
    -(void)setAge:(int)age;
    @end
    
    @implementation Person
    @synthesize age;
    
    -(bool)equals:(Person*)p
    {
       return p.age == self.age;
    }
    -(void)setAge:(int)age
    {
       self.age = age;
       if ([self.delegate respondsToSelector:@selector(onAgeChange:)])
        [self.delegate onAgeChange:self];
    }
    @end

    枚举

    声明:

    C#
    public enum Orientation: uint {
      Vertical = 0,
      Horizontal = 1
    }
    
    Objective-C
    typedef enum Orientation : NSUInteger {
      OrientationVertical = 0,
      OrientationHorizontal = 1
    } Orientation;

    使用:

    C#
    public Orientation TextAlignment {get;set} // 属性
    
    label.TextAlignment = Orientation.Horizontal;
    
    Objective-C
    @property(nonatomic, assign) Orientation textAlignment;
    
    label.textAlignment = OrientationHorizontal; 

    反射

    获取对象类型:

    C#: 
    Type t = typeof(Person);
    
    Objective-C: 
    Class c = [Person class];

    获取实例类型:

    C#: 
    Person p = new Person();
    Type t = p.GetType();
    
    Objective-C: 
    Person *p = [[Person alloc] init];
    Class c = p.class;

    获取类型名称:

    C#: 
    string name = type.Name;
    string name = typeof(Person).Name;
    
    Objective-C: 
    NSString *name = NSStringFromClass(p.class);
    NSString *name = NSStringFromClass([Person class]);

    判断实例类型:

    C#: 
    bool isPerson = p is Person;
    
    Objective-C: 
    BOOL isPerson = [p isKindOfClass:c];

    判断是否继承:

    C#: 
    bool isInherited = p is Person;
    bool isInherited = p.GetType().IsSubclassOf(typeof(Person));
    bool isInherited = typeof(ChildPerson).IsSubclassOf(typeof(Person));
    bool isInherited = typeof(Person).IsAssignableFrom(typeof(ChildPerson));
    
    Objective-C: 
    BOOL isInherited = [[p class] isSubclassOfClass:[Person class]];
    BOOL isInherited = [[ChildPerson class] isSubclassOfClass:[Person class]];

    判断是否实现接口/协议:

    C#: 
    bool isImplemented = p is IEquatable;
    bool isImplemented = typeof(IEquatable<>).IsAssignableFrom(p.GetType());
    bool isImplemented = typeof(IEquatable<>).IsAssignableFrom(typeof(Person));
    bool isImplemented = typeof(Person).GetInterfaces().Contains(typeof(IEquatable<>));
    
    Objective-C: 
    BOOL isImplemented = [p class conformsToProtocol:@protocol(IEquaatable)];

    从类型名称创建实例:

    C#: 
    object instance = Activator.CreateInstance(Type.GetType("ChildPerson"));
    
    Objective-C: 
    id instance = [[NSClassFromString("ChildPerson") alloc] init];

    获取、调用方法:

    C#: 
    MethodInfo method = type.GetMethod("PrintAge");
    bool hasMethod = method != null;
    method.Invoke(p, null);
    
    Objective-C: 
    SEL method = @selector(printAge);
    BOOL hasMethod = [p respondsToSelector: method];
    [p performSelector:method];

    获取属性:

    C#: 
    object age = p.GetType().GetProperty(“Age”).GetValue(p, null);
    foreach(PropertyInfo pi in typeof(Person).GetProperties())
    {
      // pi.Name
    }
    
    Objective-C: 
    id age = [p valueForKey:@"Age"];
    unsigned int propertyCount = 0;
    objc_property_t * properties = class_copyPropertyList([Person class], &propertyCount);
    for (unsigned int i = 0; i < propertyCount; ++i) {
      objc_property_t property = properties[i];
      const char * name = property_getName(property);
    }
    free(properties);

    扩展方法

    objc里的Category可以很好的实现C#中的扩展方法。

    C#
    public static class PersonExtension {
      public static void PrintFullName(this Person p) {
        Console.WriteLine(p.GetFullName());
      }
    }
    
    Objective-C
    Person+PrintExtension.h
    #import "Person.h"
    @interface Person (PrintExtension)
    -(void)PrintFullName;
    @end
    
    Person+PrintExtension.m
    @implementation Person (PrintExtension)
    -(void)PrintFullName
    {
      NSLog(@"%@", [self getFullName]);
    }
    @end

    异常处理

    C#
      try {
      
      } catch (Exception ex) {
      
      } finally {
      
      }
    
    Objective-C
      @try {
    
      }
      @catch (NSException *exception) {
    
      }
      @finally {
    
      }

    命名空间

    objc没有命名空间机制,直接从包或者当前项目引入头文件即可。

    引用:

    C#
    using System; 
    using System.Text;
    using MyCompany.CustomNamespace;
    
    Objective-C
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import "CustomClass.h"

    内存管理

    objc中有ARC机制对应.net 中的GC,详细的可以看:http://snakcakeblog.tumblr.com/post/47765862590/grudge-match-c-gc-vs-objective-c-arc

    程序集

    在C#当中,源代码一般被编译成程序集,而在objc中,都是编译成静态链接库,而且引用方式也不相同。

    参考

    http://www.infragistics.com/community/blogs/stevez/archive/2013/05/09/c-to-objective-c-the-ultimate-guide.aspx(本文内容主要来自它,并做了一些更改)

    http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOSCh/chapters/Introduction.html

    http://www.anotherchris.net/csharp/objective-c-by-example-for-a-csharp-developer/

    http://www.cnblogs.com/chijianqiang/archive/2012/06/22/objc-category-protocol.html

    http://www.techotopia.com/index.php/Working_with_String_Objects_in_Objective-C

    http://overooped.com/post/41803252527/methods-of-concurrency

  • 相关阅读:
    抓包
    tk(三)按钮的事件绑定
    python xlrd 模块(获取Excel表中数据)
    使用pycharm搜索框和正则表达式匹配内容
    Progressbar 实例
    python获取时间
    excel用xlrd日期变成42631.0
    Python中super的用法【转载】
    python类的继承和多态
    均值的性质及其应用
  • 原文地址:https://www.cnblogs.com/lwme/p/c-sharp-to-objective-c.html
Copyright © 2020-2023  润新知