Objective-C selectors in Xamarin.iOS

  • 07/12/2017
  • 4 luettavat minuutit
    • d
    • d
    • C
    • a

Objective-C-kieli perustuu valitsimiin. Valitsin on amessage, joka voidaan lähettää objektiin tai luokkaan. Xamarinia.iOS maps instance selectorsto instance menetelmiä, ja luokan valitsimet staattisia menetelmiä.

toisin kuin normaalit C-funktiot (ja kuten C++-jäsenfunktiot), et voi suoraan kutsua valitsinta käyttäen P/Invoke-toimintoa,vaan valitsimet lähetetään Objective-C-luokkaan tai instanssiin käyttäenobjc_msgSend – funktiota.

lisätietoja Objectsguiden viesteistä löytyy Applen työskentelystä Objectsguiden kanssa.

esimerkki

Oletetaan, että haluat vedotasizeWithFont:forWidth:lineBreakMode:valitsimeen NSString.Ilmoitus (Applen dokumentaatiosta) on:

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

tällä API: lla on seuraavat ominaisuudet:

  • Palautustyyppi on CGSize Unified API: lle.
  • font parametri on NSObject-projektista johdettu Uifontti (ja tyyppi (epäsuorasti), joka on yhdistetty systeemiin.IntPtr.
  • width parametri a CGFloat on merkitty arvoon nfloat.
  • lineBreakMode parametri, a UILineBreakMode,on jo sitoutunut Xamariiniin.iOSUILineBreakModeluettelona.

kaiken yhteen laskettuna objc_msgSend julistuksen tulisi täsmätä:

CGSize objc_msgSend( IntPtr target, IntPtr selector, IntPtr font, nfloat width, UILineBreakMode mode);

ilmoittaa sen seuraavasti:

static extern CGSize cgsize_objc_msgSend_IntPtr_float_int ( IntPtr target, IntPtr selector, IntPtr font, nfloat width, UILineBreakMode mode);

voit kutsua tätä menetelmää, käytä koodia, kuten seuraavat:

NSString target = ...Selector selector = new Selector ("sizeWithFont:forWidth:lineBreakMode:");UIFont font = ...nfloat width = ...UILineBreakMode mode = ...CGSize size = cgsize_objc_msgSend_IntPtr_float_int( target.Handle, selector.Handle, font == null ? IntPtr.Zero : font.Handle, width, mode);

jos palautettu arvo olisi ollut alle 8 tavun kokoinen rakenne (kuten vanhempi SizeF, jota käytettiin ennen yhdistettyihin sovellusliittymiin siirtymistä), yllä oleva koodi olisi toiminut simulaattorissa, mutta kaatunut laitteeseen. Jos haluat kutsua valitsinta, joka palauttaa arvon alle 8 bittiä, ilmoita funktio objc_msgSend_stret :

static extern void cgsize_objc_msgSend_stret_IntPtr_float_int ( out CGSize retval, IntPtr target, IntPtr selector, IntPtr font, nfloat width, UILineBreakMode mode);

voit kutsua tätä menetelmää, käytä koodia, kuten seuraavat:

NSString target = ...Selector selector = new Selector ("sizeWithFont:forWidth:lineBreakMode:");UIFont font = ...nfloat width = ...UILineBreakMode mode = ...CGSize size;if (Runtime.Arch == Arch.SIMULATOR) size = cgsize_objc_msgSend_IntPtr_float_int( target.Handle, selector.Handle, font == null ? IntPtr.Zero : font.Handle, width, mode );else cgsize_objc_msgSend_stret_IntPtr_float_int( out size, target.Handle, selector.Handle, font == null ? IntPtr.Zero: font.Handle, width, mode );

valitsijan kutsuminen

valitsijan kutsuminen on kolmivaiheista:

  1. Hakekaa valintakohde.
  2. Hanki valitsimen nimi.
  3. Soita objc_msgSend asianmukaisin perustein.

Valintakohteet

Valintakohde on joko objekti-instanssi tai Objective-C-luokka. Jos kohde on instanssi ja tuli sidotusta Xamarinista.iOS-Tyyppi, käytä ominaisuutta ObjCRuntime.INativeObject.Handle.

jos kohde on luokka, käytä ObjCRuntime.Class saadaksesi viittauksen luokkatasoon, käytä Class.Handle ominaisuutta.

valitsijoiden nimet

valitsijoiden nimet on lueteltu Applen dokumenteissa. Esimerkiksi NSString sisältää sizeWithFont: ja sizeWithFont:forWidth:lineBreakMode: valitsijat. Upotetut ja perään johtavat pylväät ovat osa valitsimen nimeä, eikä niitä voi jättää pois.

kun sinulla on valitsijan nimi, voit luoda sille ObjCRuntime.Selector – instanssin.

soittaminen objc_msgSend

objc_msgSend lähettää viestin (valitsin) objektille. Tämä perhe offunctions kestää vähintään kaksi vaadittua argumenttia: valitsin kohde (aninstance tai luokan kahva), valitsin itse, ja kaikki argumentit tarvitaan valitsin. Instanssin ja valitsimen argumenttien on oltavaSystem.IntPtr, ja kaikkien jäljellä olevien argumenttien on vastattava tyyppiä, jonka selector odottaa, esimerkiksi nint an int, taiSystem.IntPtr kaikille NSObjectjohdetuille tyypeille. KäytäNSObject.Handleominaisuutta saadaksesi IntPtr Objective-C-tyypin ilmentymälle.

on useampi kuin yksi objc_msgSend funktio:

  • käytä objc_msgSend_stretvalitsijoille, jotka palauttavat struktin. ARM, tämä sisältää kaikki returntypes jotka eivät ole luettelo tai jokin C sisäänrakennettu tyypit (char,short, int, long, float, double). X86: ssa (simulaattorissa) tätä menetelmää on käytettävä kaikille rakenteille, jotka ovat kooltaan yli 8 tavua (CGSize on 8 tavua eikä käytä objc_msgSend_stret simulaattorissa).
  • käytä objc_msgSend_fpretniitä valitsimia varten, jotka palauttavat liukulukuarvon vain x86: ssa. Tätä toimintoa ei tarvitse käyttää käsivarteen, vaan käytä objc_msgSend.
  • pääobjc_msgsendfunction on käytössä kaikilla muilla valitsimilla.

kun olet päättänyt, mille objc_msgSend funktioille sinun on soitettava(simulaattori ja laite voivat kumpikin vaatia eri menetelmää), voit käyttää normaalia menetelmää funktion ilmoittamiseksi myöhempää kutsumista varten.

joukko valmiiksi tehtyjä objc_msgSend julistuksia löytyyObjCRuntime.Messaging.

erilaisia simulaattorilla ja laitteella tehtäviä invokaatioita

kuten edellä on kuvattu, Objective-C: llä on kolmenlaisia objc_msgSendmenetelmiä: yksi säännöllisille invokaatioille, yksi invokaatioille, jotka returnfloating point values (vain x86), ja yksi invokaatioille, jotka returnstruct values. Jälkimmäinen sisältää loppuliitteen _stret inObjCRuntime.Messaging.

jos vedotaan menetelmään, joka palauttaa tietyt struktuurit (jäljempänä kuvatut säännöt), on käytettävä menetelmää, jonka palautusarvo on ensimmäinen parametri out arvona:

// The following returns a PointF structure:PointF ret;Messaging.PointF_objc_msgSend_stret_PointF_IntPtr (out ret, this.Handle, selConvertPointFromWindow.Handle, point, window.Handle);

sääntö siitä, milloin _stret_ – menetelmää tulee käyttää, eroaa x86: lla ja käsivarrella.Jos haluat sidosten toimivan sekä simulaattorissa että laitteessa,lisää esimerkiksi seuraava koodi:

if (Runtime.Arch == Arch.DEVICE){ PointF ret; Messaging.PointF_objc_msgSend_stret_PointF_IntPtr (out ret, myHandle, selector.Handle); return ret;}else{ return Messaging.PointF_objc_msgSend_PointF_IntPtr (myHandle, selector.Handle);}

käyttämällä objc_msgSend_stret-menetelmää

kun rakennetaan ARM-järjestelmää varten, käytetäänobjc_msgSend_stretmitä tahansa arvotyyppiä, joka ei ole arvojoukko tai jokin perusjoukko (int, byte, short, long, double, float).

rakennettaessa x86: ta varten käytetäänobjc_msgSend_stretmitä tahansa arvotyyppiä, joka ei ole arvojoukko tai mikä tahansa arvojoukon perustyyppi (int, byte, short, long, double, float)ja jonka alkuperäinen koko on suurempi kuin 8 tavua.

omien allekirjoitusten luominen

seuraavia tietoja voidaan käyttää omien allekirjoitusten luomiseen tarvittaessa.

Vastaa

Sähköpostiosoitettasi ei julkaista.