SEL, selector, @selector

Discussion in 'Mac Programming' started by liptonlover, Aug 19, 2008.

  1. liptonlover macrumors 6502a

    Joined:
    Mar 13, 2008
    #1
    I am working on a small framework, and the developer using it needs to supply their drawing method to redraw certain objects. But I don't know how to get their method name or use it to call the method when I want. So far I've found SEL, selector and @selector but these don't seem to quite do the job, even though that's what NSTimer uses. Unfortunately I don't know where NSTimer.m is hidden in the computer so I can't look at that. Can anyone help?
    Nate
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    This article does a good job of explaining this:
    http://theocacao.com/document.page/264

    You will need to accept a selector and an object (or probably class, I'm not sure if you can call class methods through this mechanism, but I think so). You'll have to go through the rigamarole of setting it up to be called. You should try to enforce the number and type of arguments. You may have to do this by catching an exception.

    If you get through that article and still aren't sure how to use it, post again.

    -Lee
     
  3. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #3
    The source code to NSTimer is no-where on your computer. Apple only provide pre-compiled binaries.

    In general if you are writing something that needs to make a callback to another object, or uses a delegate you need 2 pieces of information: the object and the selector. The code below is an example

    Code:
    -(void) doSomethingWithCallbackObject:(id) target andSelector:(SEL) selector
    {
    // Do whatever the code is meant to do.
    // Now do callback
    [target performSelector:selector];
    }
    
    Pretty simply really...
     
  4. liptonlover thread starter macrumors 6502a

    Joined:
    Mar 13, 2008
    #4
    Here's my pertinent code. I was figuring things out a little bit while waiting for a reply...

    Code:
    - (void)animateIntTo:(int)x atSpeed:(float)y drawMethod:(NSString *)methodName {
    	selector=@selector(methodName);
    }
    
    
    - (void)incrementInt:(NSTimer *)aTimer {
    	[_____ performSelector:selector];
    }
    
    I read through that document really quick, I'll go over it slower in a sec but it seems like a bit much for what I'm trying to do... I just need to be able to call a method not in this class, or to be more specific specified by the developer using my framework. I don't know what the target should be either. Thanks for your help so far!
    Nate
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    You need the caller of the method to provide the target when they call your method: there is no easy way to recover the caller easily (and they may want to provide a different object anyway).

    Also @selector(methodName) will never work. @selector is a compiler directive and gets evaluated at compile time. If you really want to get passed a NSString use NsSelectorFromString, but be aware that this is relatively inefficient: you would be better accepting a SEL as per my example.

    So the code should be:

    Code:
    - (void)animateIntTo:(int)x atSpeed:(float)y withDrawTarget:(id) target drawMethod:(SEL) drawMethod{
    	[target performSelector:drawMethod];
    }
    
    
    - (void)incrementInt:(NSTimer *)aTimer {
    	[_____ performSelector:selector];
    }
    
    The caller would then looks something like this:

    Code:
    - (void) myDrawMethod
    {
    }
    
    - (void) aMethod
    {
      [frameWorkObject animateIntTo:xCoord atSpeed:ySpeed withDrawTarget:self drawMethod:@selector(myDrawMethod)];
    }
    
     
  6. liptonlover thread starter macrumors 6502a

    Joined:
    Mar 13, 2008
    #6
    sorry I took so long, wasn't around.

    Code:
    - (void)animateIntTo:(int)x atSpeed:(float)y withDrawTarget:(id) target drawMethod:(SEL) drawMethod{
    	[target performSelector:drawMethod];
    	[_____ performSelector:selector];
    [frameWorkObject animateIntTo:xCoord atSpeed:ySpeed withDrawTarget:self drawMethod:@selector(myDrawMethod)];
    
    can we go over each pertinent line please?
    I know what my line does, you get a target and a method. But what about the middle ones? They're the same, only in different methods. What does performSelector: do?
    The last I can see is just calling the animate method.
     
  7. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #7
    I've no idea what your line with _____ in is meant to do:it's your code not mine!

    performSelector: does exactly what it's name suggests. It causes the object that this message is passed to to perform the selector passed. We use it to allow us to call any method that is passed.

    It seems to me that you are in above your head here and should go and learn the basics of Objective-C including all of the dynamic features of the language before attempting this sort of project. I would read (and ensure you understand) all of the Object-C language guide, especially the "How Messaging Works" section.
     
  8. liptonlover thread starter macrumors 6502a

    Joined:
    Mar 13, 2008
    #8
    I put it there because I didn't know what I need there... sorry. I'll read the guide, but in general I hate Apple's tutorials and documentation and all that. I have trouble understanding it :mad:
    Thanks for your help!
    Nate
     
  9. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #9
    The problem with the Cocoa Programming for Mac OS X book is that it is very good at telling you how things are done but rather poor at telling you why things work. Seems rather sparse on the theory, which is where the Apple documentation comes in.
     

Share This Page