從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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM