icsadam 2009.06.04. 15:30

C# vs. Objective-C

Nem tagadom, hogy a .Net világból jöttem. Gondolom sokan vannak így, nekik szól az alábbi kis összefoglaló. Egyébként a C# 4-ben egyre több ObjC-re hajazó megoldás jelent meg, nem is tudom miért :) Node semmi rizsa, következzen a lényeg!

Változók

ObjC C#
int i = 10;
BOOL b = YES;
id anObject;
NSString* h = @"Hello";
int i = 10;
bool b = true;
(dynamic) anObject;
string h = "Hello";

 

Metódushívás

ObjC C#
[anObject method];
[anObject methodWithParam:param];
s=[NSString stringWithFormat:[item format]];
NSString* s = [text uppercaseString];
r = [system loginWithName:name password:pwd];
anObject.method();
anObject.method(param);
s= String.Format(item.format());
string s = text.ToUpper();
r = system.Login(name, pwd);

 

Propertyk elérése

ObjC C#
album.title = @"Birthday";
int count = album.picnum;
album.title = "Birthday";
int count = album.picnum;

 

Példányosítás

ObjC C#
NSString* szoveg=[NSString alloc] init];
NSArray* arr =[[NSArray alloc] initWithObjects:
   "Me",@"Myself",@"I",nil];
String szoveg=new String();
String[] arr = new string[]
{"Me","Myself","I"};

 
Konstruktor

ObjC C#
- (id) init
{ 
  if ( self=[super init] )
  {
    //constructor logic
  }
  return self;
}
public ClassName()
{

  // constructor logic



}

 

Destruktor

ObjC C#
- (void) dealloc
{
  //release objects
  [anObject release];
  [super dealloc];
}
~ClassName()
{

  //release resources

}

 

Osztályok

ObjC C#
//Alma.h
#import <Foundation/NSObject.h>
@interface Alma:NSObject {
    NSString* szin;
    int suly;
}
@property(retain) int suly;
+ (BOOL) create();
- (void) kifacsar();
@end


//Alma.m
#import "Alma.h"
@implementation Alma

+ (BOOL) testAlma: (Alma* a)
{
  if (a.suly>3)
  { 
    return YES;
  }
  else return NO;
}

- (void) kifacsar() {
  NSLog(@"Facsarom");
}
@end
class Alma 
{
  String szin;
  int Suly {get; set;);
  public static bool test(Alma a)
  {  
    return (a.suly > 3);
  }
  public void kifacsar()
  {
    Console.WriteLine("facsarom");
  }
}


Interfészek

ObjC C#
@protocol Printable
- (void) print;

@end
interface Printable
{
  void print();
}

 


Kiíratás, loggolás

ObjC C#
NSLog(@"Debug info");
System.Diagnostics.Trace.Log.WriteLn("Debug info");

 

Újabb időspóroló cikk következik. Mi történik, ha forráskódot copypastelünk a hivatalos Apple referenciából? (pl. innen) Hát EZ:

 

 

 

 

 

 

 

Hogy mivan?

Line Location ProxyAppDelegate.m:44: error: syntax error before 'void'
Line Location ProxyAppDelegate.m:44: error: syntax error at 'OTHER' token
Line Location ProxyAppDelegate.m:44: error: syntax error at 'OTHER' token
Line Location ProxyAppDelegate.m:44: error: syntax error at 'OTHER' token

Ebből kéne rájönni, mi a kínja... Ötlet? Najó segítek, mi a különbség a két sor között?


 

Igen, a kötőjel. Figyeljetek oda.

Kezdő iPhone milliomosként, mikor először láttam ObjC forrást, a legfurább az volt (azon kívül, hogy [] között van a metódushívás), hogy minden @"string" előtt ott egy kukac.

Elég szokatlanul néz ki elsőre, de mindennek megvan az oka.

char *cString = "Ódivatú C string vagyok";
NSString *nsString = @"Okosügyes NSString objektum vagyok";

Bizonyára tudod, hogy az Objective C a sima C-nek egy kibővítése. Sima C-ben sem objektumok nincsenek, sem stringek. Ha kukac nélkül írsz be egy stringet, az egy char tömb lesz, és egy pointert kapsz a legelső karakterre. Ez valljuk be, nem túl objektumorientált.

Ha a nyitó idézőjel elé egy @-ot teszel, akkor a fordító egy NSString objektumot fog legyártani a megadott karakterekből.

C String és NSString

Fő különbség a kettő között, hogy az NSString minden esetben Unicode karakterekből áll, míg egy C string bármilyen kódolású lehet. Fontos tudni, hogy az NSString immutable, vagyis létrehozás után nem módosítható. Másik érdekesség, hogy a @-cal létrehozott stringek mindvégig a memóriában maradnak, hiába release-eljük őket (?). 

A két formátum között az

- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;

+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc
//és a 
- (const char *)cStringUsingEncoding:(NSStringEncoding)encoding;

metódusok biztosítják az átjárást. Mindkét esetben meg kell adni a kódolást. A választékot az NSString.h-ban találjuk:

/* Note that in addition to the values explicitly listed below, NSStringEncoding supports encodings provided by CFString.
See CFStringEncodingExt.h for a list of these encodings.
See CFString.h for functions which convert between NSStringEncoding and CFStringEncoding.
*/
enum {
    NSASCIIStringEncoding = 1,		/* 0..127 only */
    NSNEXTSTEPStringEncoding = 2,
    NSJapaneseEUCStringEncoding = 3,
    NSUTF8StringEncoding = 4,
    NSISOLatin1StringEncoding = 5,
    NSSymbolStringEncoding = 6,
    NSNonLossyASCIIStringEncoding = 7,
    NSShiftJISStringEncoding = 8,
    NSISOLatin2StringEncoding = 9,
    NSUnicodeStringEncoding = 10,
    NSWindowsCP1251StringEncoding = 11,    /* Cyrillic; same as AdobeStandardCyrillic */
    NSWindowsCP1252StringEncoding = 12,    /* WinLatin1 */
    NSWindowsCP1253StringEncoding = 13,    /* Greek */
    NSWindowsCP1254StringEncoding = 14,    /* Turkish */
    NSWindowsCP1250StringEncoding = 15,    /* WinLatin2 */
    NSISO2022JPStringEncoding = 21,        /* ISO 2022 Japanese encoding for e-mail */
    NSMacOSRomanStringEncoding = 30,

    NSUTF16StringEncoding = NSUnicodeStringEncoding,      /* An alias for NSUnicodeStringEncoding */

#if MAC_OS_X_VERSION_10_4 <= MAC_OS_X_VERSION_MAX_ALLOWED
    NSUTF16BigEndianStringEncoding = 0x90000100,          /* NSUTF16StringEncoding encoding with explicit endianness specified */
    NSUTF16LittleEndianStringEncoding = 0x94000100,       /* NSUTF16StringEncoding encoding with explicit endianness specified */

    NSUTF32StringEncoding = 0x8c000100,                   
    NSUTF32BigEndianStringEncoding = 0x98000100,          /* NSUTF32StringEncoding encoding with explicit endianness specified */
    NSUTF32LittleEndianStringEncoding = 0x9c000100        /* NSUTF32StringEncoding encoding with explicit endianness specified */
#endif
};
typedef NSUInteger NSStringEncoding;

Mindent megtudhattok az NSString programozásáról a String Programming Guide for Cocoa doksiból.

Előbb-utóbb mindenki beleszalad ebbe a problémába, és több-kevesebb próbálkozás után rájön, hogy ObjCben nem lehet csak úgy emberi formátumra hozni a BOOL típust. Ezt az időt szeretnénk nektek megspórolni az alábbi kis függvénnyel, amit a Learn Objective-C on the Mac című könyvből loptunk egyenesen a 14. oldal aljáról, íme:

NSString *boolToString (BOOL yesNo)
{
    if (yesNo == NO) {
        return (@"NO");
    } else {
        return (@"YES");
    }   
}

Kicsit bővebben

Habár az objektumoknak van describe metódusuk, ami a Java-s/C#-os toString megfelelője, ez nem használható a BOOLnál. Az Objective-C BOOL típusa valójában egy szerencsétlen char megerőszakolása, amint az objc.h-ban láthatjuk:

typedef signed char		BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#define OBJC_BOOL_DEFINED

#define YES             (BOOL)1
#define NO              (BOOL)0

Namost C-ben logikailag minden igaz, ami nem 0. Megfordítva, a 0 az tuti hamis, a többi meg igaz. Ezért hasonlítunk előbb a NO-val, mert az objCben és sima C-ben is hamis, minden más pedig "YES" lesz az else ágban. Így jól működik sima C bool és ObjC BOOL paraméterrel is.

süti beállítások módosítása