Can't call a method with another method, what am I missing? - objective-c

Extremely basic objective-c question here. I want to call a method from within another method and send a variable from the first method to the second method, but I'm not sure how to handle this with #implementation, etc.
Here is what I want:
-(int) isItFav:(int) favNum
{
// some code
}
- (IBAction)myBar:(UISegmentedControl *)sender
{
// some code
int x = 10;
[isItFav x];
}
This causes as error, as isItFav is an undeclared identifier. Can someone please tell me how to fix this up?

If both myBar: and isItFav: are in same class:
int returnedValue = [self isItFav:x];
If in different class, then
int returnedValue = [objectOfClassWhichContainsIsItFavMethod isItFav:x];
This is Objective-C. Please see tutorials and manuals.

[receiverOfCall method:param];
This case:
int result = [self isItFav:x];

Message Call Format is
[sender message:params]

Related

Objective C - caller Object of a method [duplicate]

Example: When my method -fooBar gets called, I want it to log in the console which other method of which other class called it.
Right now, I only know how to log the method name of fooBar itself and it's class, with this:
_cmd
[self class]
Is this possible to figure out?
In fully optimized code, there is no 100% surefire way to determine the caller to a certain method. The compiler may employ a tail call optimization whereas the compiler effectively re-uses the caller's stack frame for the callee.
To see an example of this, set a breakpoint on any given method using gdb and look at the backtrace. Note that you don't see objc_msgSend() before every method call. That is because objc_msgSend() does a tail call to each method's implementation.
While you could compile your application non-optimized, you would need non-optimized versions of all of the system libraries to avoid just this one problem.
And this is just but one problem; in effect, you are asking "how do I re-invent CrashTracer or gdb?". A very hard problem upon which careers are made. Unless you want "debugging tools" to be your career, I would recommend against going down this road.
What question are you really trying to answer?
How about this:
NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1];
NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:#" -[]+?.,"];
NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString componentsSeparatedByCharactersInSet:separatorSet]];
[array removeObject:#""];
NSLog(#"Class caller = %#", [array objectAtIndex:3]);
NSLog(#"Method caller = %#", [array objectAtIndex:4]);
Credits to the original author, intropedro.
It's not possible in the general case without actually walking the stack. There's not even a guarantee that another object send the message that called the method. For example, it could be called from a block in a signal handler.
NSLog(#"Show stack trace: %#", [NSThread callStackSymbols]);
See backtrace(3).
User the below method
Pass index for which you want to display method and pass -1 if you want to display full stack of method
+(void) methodAtIndex:(int)index{
void* callstack[128];
int frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
if (index == -1) {
for (int i = 0; i < frames; ++i) {
printf("%s\n", strs[i]);
}
}
else {
if (index < frames) {
printf("%s\n", strs[index]);
}
}
free(strs);
}
This information can be obtained using DTrace.
Make a macro that adds the __FUNCTION__ to the function name to the function call. This macro will then call your function with an extra parameter of a char* to the target function.
I was trying to catch who, how and when changes window's size and did some handwork:
- (void)logWindowWidth:(NSString *)whoCalls {
NSLog(#"%#", whoCalls);
NSLog(#"self.window.size.width %f", self.window.size.width);
}
-(void)someMethod {
[self logWindowWidth:#"someMethod - before"];
...
[self logWindowWidth:#"someMethod - after"];
}
-(void)anotherMethod {
[self logWindowWidth:#"anotherMethod - before"];
...
[self logWindowWidth:#"anotherMethod - after"];
}

Variable out of IBAction

I have problem that im trying to get solve for like week.
My goal is to get variable out of my IBAction, to use for example in -(void)viewDidLoad..
But as far as I am now I can use my variable only in my IBAction..
- (IBAction) changeLat:(NSNumber *)str {
longi = str;
double lop = longi.doubleValue;
NSLog(#"%f",lop);
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog (#"%#",lop);
}
It NSLog shows everything fine in action, but in view did load it doesn't even recorganize it.
If you create a variable inside of -IBAction, the scope of that variable is only that method, so you cannot access to that variable outside it.
If you want your variable to be global to your class, you have to create it in the declaration of your class, like this:
#interface MainViewController () {
#private
double lop;
}
Put this at the beginning of your .m file, and then lop would be accesible in all your class.
You can read more about the scope of the variables here:
http://www.techotopia.com/index.php/Objective-C_Variable_Scope_and_Storage_Class
Actually, IBAction is converted to void by the preprocessor. It's used by Interface Builder as a label that identifies this method as an action able to be related from an IB Object.
There's no way (AFAIK) to use two return types in a function (for example `(IBAction double)´, equivalent to ´(void double)´), but a good practice could be something like this:
- (IBAction)changeLatAction:(id)sender {
NSNumber *str = <get the NSNumber from a valid place>;
[self changeLat:str];
}
- (double) changeLat:(NSNumber *)str {
longi = str;
double lop = longi.doubleValue;
NSLog(#"%f",lop);
return ????;
}
Your first declaration of changeLat seems to be wrong, because as a first parameter you'll always get the "sender" or "caller" object, related from IB (when called from an action, of course), so, you need to get the str value from a valid place.
Cheers.

how to call a function of a same class from other functions of the same class-Objective C

But i'm getting errors when declaring like this.
#implementation data
-(void)SwapEndian:(uint8_t*)pData withBOOLValue:(bool)bIsAlreadyLittleEndian
{
data* datas = [data alloc];
[datas swapEndians:(uint8_t)&pData[nIndex] withSize:(sizeof(uint32_t));
}
-(void)swapEndians:(uint8_t*)pData withnByteSize:(int const)nByteSize
{
NSLog(#"swapEndians!!");
}
#end
How to call a function from other function inside the same class?
You can use self keyword to achieve this.
[self yourFunctionName];
First things first:
data* datas = [data alloc]; // Where is your init? Don't use un-initialized objects!
[datas swapEndians:(uint8_t)&pData[nIndex] withSize:(sizeof(uint32_t));
Second thing:
If the method you are trying to call is the second one from you code, you have a typo in the selector!
That line should read:
[datas swapEndians:&pData[nIndex] withnByteSize:sizeof(uint32_t)];
Third thing:
You send messages to yourself by using self.
First of all class name should start with capital letter, here is I think you are tying to do
#implementation Data //changed it just naming convention
-(void)swapEndian:(uint8_t*)pData withBOOLValue:(bool)bIsAlreadyLittleEndian
{
[self swapEndians:(uint8_t)&pData[nIndex] withSize:(sizeof(uint32_t));
}
-(void)swapEndians:(uint8_t*)pData withnByteSize:(int const)nByteSize
{
NSLog(#"swapEndians!!");
}
#end

How to call my method in cocoa, self doesn't work

Working on a program that will record some things from the webcam when a user presses physical buttons connected to the mac via phidgets. Have call methods on other places in my app simply doing [self method: input], but on one place it doesn't work. What could be wrong?
This is the method i want to run if i get inputchange in my program.
Also i do -(void)reportButton2:(NSInteger)inputVal:(NSInteger)inputInd; in my .h file.
-(void)reportButton2:(NSInteger)inputVal:(NSInteger)inputInd {
//NSLog(#"phidget för port = %%d med signal %%d", ind, val);
if(inputVal == 1)
{
NSError* error;
NSFileManager* deleteMgr = [NSFileManager defaultManager];
NSString* path = #"/Users/Shared/tempFile.mov";
[deleteMgr removeItemAtPath:path error:&error];
[mCaptureMovieFileOutput recordToOutputFileURL:[NSURL fileURLWithPath:#"/Users/Shared/tempFile.mov"]];
}
else if(inputVal == 0)
{
[mCaptureMovieFileOutput recordToOutputFileURL:nil];
}
}
The code below give me result if imput from the buttons change. Here i just can't seem to call reportbutton2.
If i try to use [self reportButton2..] in gives me "Use of undeclared identifier 'self'"
int gotInputChange(CPhidgetInterfaceKitHandle phid, void *context, int ind, int val) {
what to do here?
return 0;
}
The problem is that gotInputChange is a C function not a Objective C method and so has no udea what self is as it does not belong to a class.
for [self reportButton2... = to work it needs to be a method in your class
I usually put something like this at the top of callbacks like gotInputChange:
MyObject *self = (id)context;
Then I can use self throughout the function as if it were a method.
The other thing being in a function makes harder is asserting conditions. The regular assertion macros, such as NSAssert and NSParameterAssert, require both of the implicit arguments to every method (self is one of them) to exist. In a C function, you must use NSCAssert, NSCParameterAssert, etc. instead.
You can also use your delegate.
SomeNameAppDelegate *delegate = (SomeNameAppDelegate *)[[NSApplication sharedApplication] delegate];
[delegate yourMethodName];
It works like in example if your target method in AppDelegate class. But when you have an access to delegate, you can create a pointers to necessary classes and use them over delegate.
Quickest but not soo nice way is to make your Class a singleton and access it from the gotInputChange function.
Okay thanks! Din't have any clue that it was C would never have solved it by myself. Did some googeling and this one did the trick for me.
[(id)context performSelectorOnMainThread:#selector(reportButton2:)withObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:ind], [NSNumber numberWithInt:val], nil] waitUntilDone:NO];

How to call a method in init method?

My program looks like this:
-(id)init
{
if ( (self = [super init]) )
{
//TargetWithActions *targetActions= [[TargetWithActions alloc] init];
[self countDownSpeed123];
}
return self;
}
-(void)countDownSpeed123
{
countDownSpeed = 5.0f;
}
#end
warning: 'TargetWithActions' may not respond to '-countDownSpeed123'
I am getting the warning in this way. Where I am wrong in my program. Please explain ?
Thank You.
If I need to use the countDownSpeed value in another class, how can I retain the value ? How can I use in the other class? I think retain works for pointer types.
EDIT:
Sorry for my bad coding and negligence. I have did mistakes in my program which are very blunt.
Thanks for answering.
First: I did not declare the
function (
-(void)countDownSpeed123; )in
interface.
Second: I did not include the
following in my class where I needed
the (countDownSpeed) value.
TargetWithActions *targetActions= [[TargetWithActions alloc] init];
[targetActions countDownSpeed123];
Now, I got what I need.
Thank You.
In the class where you trying to use
TargetWithActions, and in TargetWithActions.m make sure you
have #import
"TargetWithActions.h".
In TargetWithActions.h make sure
in your class declaration
you declared the method -(void)countDownSpeed123;
Sorry I don't understand what are you trying to do with countDownSpeed123, it does not return anything (void) so I'm not quite sure what you want to retain. If the method returns simple value like float or int you don't have to retain it, it is passed by value - it will be copied.
Sorry for my bad coding and negligence. I have did mistakes in my program which are very blunt. Thanks for answering.
First: I did not declare the function ( -(void)countDownSpeed123; )in interface.
Second: I did not include the following in my class where I needed the (countDownSpeed) value.
TargetWithActions *targetActions= [[TargetWithActions alloc] init];
[targetActions countDownSpeed123];
Now, I got what I need.
Thank You.