2010-03-17 3 views
6

Je sais que javascript, par exemple prend en charge les fonctions à l'intérieur des fonctions, comme ceci:Est-ce que l'iPhone SDK Objective C prend en charge les fonctions à l'intérieur des fonctions?

function doSomething(){ 

    function doAnothingThing(){ 
    //this function is redefined every time doSomething() is called and only exists inside doSomething()  
    } 

    //you can also stick it inside of conditions 

    if(yes){ 
    function doSomethingElse(){ 
     //this function only exists if yes is true 
    } 
    } 


} 

Est-ce que l'objectif-c soutenir cela? Exemple théorique:

-(void) doSomething:(id) sender{ 
    -(void) respondToEvent: (id) sender{ 
    //theoretically? ... please? 
    } 
} 

BONUS: Quel est le terme approprié pour une fonction "locale"?

+0

Javascript permet seulement cela, car il ne dispose pas de véritables classes. C'est le seul moyen d'encapsuler des fonctions. – TechZen

Répondre

8

Le terme usuel est fonction imbriquée. gcc supporte les fonctions imbriquées en tant qu'extension de C (désactivé par défaut). Je ne pense pas que cette option est disponible avec Objective-C (ou C++) avec gcc cependant, et même si elle était c'est probablement pas une bonne idée de l'utiliser (la portabilité, etc.).

gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

+0

Dans les fonctions Obj-C sont appelés, « Méthodes » Je suis assez certain, c'est probablement la raison pour laquelle il a formulé la question, « Méthodes emboîtées » – NpC0mpl3t3

+0

@ NpC0mpl3t3: Je ne vois pas les mots « imbriqués » ou « méthode » partout dans la question de l'OP? –

7

Par défaut Xcode fonctions imbriquées ne permettant pas. Si vous souhaitez les activer, ouvrez l'Info pour votre projet, allez dans l'onglet Build, et réglez "Other C flags" (sous la section "GCC 4.2 - Language") sur "-fnested- les fonctions".

(Ceci est stocké dans votre fichier project.pbxproj comme « OTHER_CFLAGS = « -fnested-fonctions »; »

+0

+1 pour obtenir des instructions sur l'activation – Moshe

+0

Notez que cela ne fonctionne que pour C, je crois - pas Objective-C ou C++. –

+1

@ Paul vous pouvez imbriquer une fonction C à l'intérieur d'une méthode Objective-C très bien. Vous ne pouvez pas imbriquer une méthode dans une autre méthode, mais cela a du sens. Objective-C est une exécution très fine au-dessus du C simple (ou C++). –

9

Un peu en retard, mais vous pouvez placer un bloc en ligne en fonction, quel type d'actes comme vos questions de fonction imbriquées.

-(int)addNumbers:(int)a withB:(int)b withC:(int)c { 

    // inline block 
    int(^inlineaddNumbers)(int, int) = ^(int a, int b) { 
     return a + b; 
    }; 

    if(a == 0) return inlineaddNumbers(b,c); 
    else return inlineaddNumbers(a,c); 
} 

il est un peu en désordre, mais ça marche!

0

@Moshe vous ne pouvez pas fournir réellement les fonctions imbriquées à l'intérieur de l'objectif C. place, vous pouvez utiliser la fonction dans le dernier Swift 3 qui active cette fonctionnalité, ce sera comme ci-dessous:

func someFunction(input:String)->String 
{ 
    var inputString = input; 
    func complexFunctionOnString() 
    { 
     inputString = "Hello" + input; 
    } 
    complexFunctionOnString(); 
    return inputString; 
} 
someFunction("User"); 
1

L'expansion de la réponse fournie par Gui13 un peu, avec des paramètres d'objet.

L'extrait de code suivant montre comment dessiner un ensemble 11x5 de UILabels.

// inline block - to be called as a private function 
UILabel *(^createLabel)(CGRect, NSString *, UIColor *) = ^UILabel *(CGRect rect, NSString *txt, UIColor *color) { 
    UILabel *lbl = [UILabel new]; 
    lbl.frame = rect; 
    lbl.textColor = color; 
    lbl.backgroundColor = [UIColor whiteColor]; 
    lbl.font = [UIFont systemFontOfSize:30.f]; 
    lbl.textAlignment = NSTextAlignmentCenter; 
    lbl.text = txt; 
    return lbl; 
}; 
// loop to create 11 rows of 5 columns over the whole screen 
float w = CGRectGetWidth([UIScreen mainScreen].bounds); 
float h = CGRectGetHeight([UIScreen mainScreen].bounds); 
float top = h/10;   //start at 10% from top 
float vOffset = h/13;  //space between rows: 7.6% of screen height 
NSArray *xFrom, *xTo;  //columns to start at 5%, 20%, 40%, 60%, 80% 
xFrom = @[@(1.f/20),  @(1.f/5),  @(2.f/5),  @(3.f/5),  @(4.f/5)]; 
xTo = @[@(1.f/5-1.f/16), @(2.f/5-1.f/16), @(3.f/5-1.f/16), @(4.f/5-1.f/16), @(19.f/20)]; 
#define SFMT(format...) [NSString stringWithFormat:format] 
for (int row=0; row<11; row++) { 
    for (int col=0; col<5; col++) { 
     CGRect rect = CGRectMake([xFrom[col] floatValue]*w, top+row*vOffset, [xTo[col] floatValue]*w-[xFrom[col] floatValue]*w, vOffset*0.9); 
     UILabel *lbl = createLabel(rect, SFMT(@"%i-%i", row, col), [UIColor blueColor]); 
     [<my-view> addSubview:lbl]; 
    } 
} 

Voici la sortie de ce code:

code output