How would I go about passing parameters when calling a void method? I understand that you can do something like this:
-(void)viewDidLoad {
[self callMethod];
}
-(void)callMethod {
//stuff here
}
But how would I pass a parameter, such as an NSString, to the callMethod method?
Here is an example with an integer parameter.
-(void)viewDidLoad {
[self callMethodWithCount:10];
}
-(void)callMethodWithCount:(NSInteger)count {
//stuff here
}
In objective-c the parameters are included within the method name. You can add multiple parameters like this:
-(void)viewDidLoad {
[self callMethodWithCount:10 animated:YES];
}
-(void)callMethodWithCount:(NSInteger)count animated:(BOOL)animate{
//stuff here
}
It seems you may be misunderstanding what the void in the beginning of the method means. It's the return value. For a void method, nothing is returned from calling the method. If you wanted to return a value from your method you would do it like this:
-(void)viewDidLoad {
int myInt = [self callMethodWithCount:10 animated:YES];
}
-(int)callMethodWithCount:(NSInteger)count animated:(BOOL)animate{
return 10;
}
You define your method to return an int (in this example it always returns 10.) Then you can set an integer to the value returned by calling the method.
- (void)callMethod:(NSString *)string
{
}
Where string is your parameter so you would call
NSString *myString = #"your string here......";
[self callMethod:myString];
Related
In the MyViewController.h file:
#property (nonatomic, copy, nullable, class) void (^saveMetadataSuccess)(MyViewController*const _Nullable myViewController);
In the MyViewController.m file:
void (^saveMetadataSuccess)(MyViewControllerr* const myViewController) = nil;
+ (void)setSaveMetadataSuccess:(void (^)(MyViewController* const))newMetadataSaveSuccess {
saveMetadataSuccess = [newMetadataSaveSuccess copy];
}
+ (void (^)(MyViewController* const))saveMetadataSuccess {
return saveMetadataSuccess;
}
And finally the method which I don't understand:
- (void)success {
dispatch_async(dispatch_get_main_queue(), ^{
MyViewController.saveMetadataSuccess(self);
});
}
From my understanding, saveMetadataSuccess is a getter, but MyViewController.saveMetadataSuccess(self);seems to set something.
Can somebody enlighten me?
Thanks
MyViewController.saveMetadataSuccess is a getter and it returns a block that then being called with a param (self).
So it's like a function that returns other function.
Also you must not just call MyViewController.saveMetadataSuccess(self); because MyViewController.saveMetadataSuccess is nullable and it will crash if MyViewController.saveMetadataSuccess is null.
You have to check MyViewController.saveMetadataSuccess first:
- (void)success {
dispatch_async(dispatch_get_main_queue(), ^{
if (MyViewController.saveMetadataSuccess) {
MyViewController.saveMetadataSuccess(self);
}
});
}
for example:
-(void) myExample {
..do something
}
void myOther(){
how to call myExample function here
}
When you call myOther, pass self reference. you should define the C method like this:
void myOther(id callBack)
Now you have self reference in c function.
void myOther(id callBack){
[callBack myExample];
}
If both methods are in same Class than you can directly call First method from Second methods as follows:
-(void) myExample {
..do something
}
void myOther(){
call to myExample function
[self myExample];
}
read docs here: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html
void getInputSource() {
TISInputSourceRef source = TISCopyCurrentKeyboardLayoutInputSource();
NSLog(#"languages: %#", TISGetInputSourceProperty(source, kTISPropertyBundleID));
NSLog(#"localized name: %#", TISGetInputSourceProperty(source, kTISPropertyLocalizedName));
[self awakeFromNib];
}
-(void) awakeFromNib {
self.statusBar = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
NSImage* icon = [NSImage imageNamed:#"icon.png"];
self.statusBar.image = icon;
}
I am trying to create a simple bridge between lua and my 'native' code. Using the following code I am adding an LuaObject class so that it can used from the lua code.
-(instancetype) init
{
if((self = [super init]))
{
// temp for testing script
L = luaL_newstate();
luaL_openlibs(L);
[self registerClazz:[LuaObject class]];
[self pushFunction:getObjectWithName name:#"getObjectWithName"];
}
return self;
}
-(void) pushFunction:(lua_CFunction)function name:(NSString*)name
{
lua_pushcfunction(L, function);
lua_setglobal(L, [name cStringUsingEncoding:NSASCIIStringEncoding]);
}
int getObjectWithName(lua_State *luaState)
{
NSString *name = [NSString stringWithUTF8String:lua_tostring(luaState, 1)];
lua_pop(luaState, 1);
LuaObject *luaObject = [objectMap objectForKey:name]
void *luaUserdataPtr = lua_newuserdata(luaState, sizeof(LuaObject*));
void *luaObjectPtr = (__bridge_retained void *)luaObjectPtr;
memcpy(ptr, &luaObjectPtr, sizeof(LuaObject*));
luaL_getmetatable(luaState, "LuaObject");
lua_setmetatable(luaState, -2);
return 1;
}
-(void) registerClazz:(Class)clazz
{
luaL_Reg methods[] = {
{ "talk", &proxyLuaObjectCall },
{ "say", &proxyLuaObjectCall },
{ NULL, NULL }
};
luaL_newmetatable(L, "LuaObject");
luaL_newlib(L, methods);
lua_setfield(L, -2, "__index");
lua_setmetatable(L, -2);
}
int proxyLuaObjectCall(lua_State *luaState, void* caller)
{
luaL_checkudata(luaState, 0, "LuaObject");
}
Now when proxyLuaObjectCall is called from lua, I want to be able to retrieve the instance of the LuaObject on which the method is being called. Above code works perfectly when calling a method without any arguments. But when calling a method that has any arguments the code fails with the error
bad argument #0 to '' (LuaObject expected, got table).
For example when using the following code in lua:
This works perfectly:
myObject = getObjectWithName("nominator");
myObject.talk();
This fails miserably
myObject = getObjectWithName("nominator");
myObject.say("And the winner is");
// Result: bad argument #0 to 'say' (LuaObject expected, got table).
--
myObject = getObjectWithName("nominator");
myObject.say("And the winner is", "Joan");
// Result: bad argument #0 to 'say' (LuaObject expected, got string).
I have tried changing the index when calling a method that has arguments but nothing on the stack contains a reference to the LuaObject instance.
What am I doing wrong here? What should I do to retrieve the instance of the LuaObject on which the method is called?
Everything looks good to me, but you probably should be calling it using the method notation:
myObject = getObjectWithName("nominator");
myObject:say("And the winner is");
myObject:say("") is the same as myObject.say(myObject, ""), which is what your API seems to expect.
On the other hand, #siffiejoe may be right as according to this PiL example, it should probably be luaL_checkudata(luaState, 1, "LuaObject"). In fact, you may need both of these changes to make it work.
I have NSTextField with placeholder. And it's binded to some integer property. So I want to display empty text in the field (with placeholder shown) when binded integer is zero.
Is it possible to do it?
(Update)
I discovered that this can be done through NSNumberFormatter - it has —(void) setZeroSymbol: (NSString*) string method. Not tried yet this in practice...
You could use an NSValueTransformer.
(Just in case)Create a new class, subclass from NSValueTransformer. In the implementation, add something like this:
+(Class)transformedValueClass {
return [NSString class];
}
-(id)transformedValue:(id)value {
if (value == nil) {
return nil;
} else {
if ([value integerValue] == 0) {
return #"";
} else {
return [NSString stringWithFormat:#"%d", [value stringValue]];
}
}
}
In Interface Builder, select your field, go to the bindings tab, and in the Value Transformer drop down, either select or type in your class name you made. This should prevent you from having to worry about modifying it elsewhere. I'm not 100% positive about it showing the placeholder (I don't have a Mac available right now).
EDIT:
I can confirm that this does indeed work. Here is a link to a github project I made to show how to use it: https://github.com/macandyp/ZeroTransformer
check the integer value before binding, if you are binding at runtime. Try
int i;
if (i == 0)
{
txt.placeholder = #"text";
}
else
{
[txt setStringValue:[NSString stringWithFormat:#"%d",i]];
}
You can not do conditional binding.
You need to create another property that will hold the value based on condition and use that property and bind to textfield.
I am using bindedString and bindedInteger. bindedString is bound to text field.
Whenever some action is performed it is updated.
- (id)init{
self = [super init];
if (self) {
self.bindedString=#"place holder string";
}
return self;
}
- (IBAction)button:(id)sender {
if (self.bindedInteger==0) {
self.bindedString=#"place holder string";
}
else{
self.bindedString=[NSString stringWithFormat:#"%ld",self.bindedInteger];
}
}
I would like to know if an instance implements a specific method. I could use respondsToSelector: but it returns YES if the instance inherits the method...
I could loop through the methods of class_copyMethodList(), but since I might want to check a lot of instances, I wanted to know if there was a simpler solution (like repondsToSelector:, but restricted to the class itself...)
edit: since I really think there is no function or method doing that, I wrote mine. Thanks for your answers, here is the method if it can be of any use :
+ (BOOL)class:(Class)aClass implementsSelector:(SEL)aSelector
{
Method *methods;
unsigned int count;
unsigned int i;
methods = class_copyMethodList(aClass, &count);
BOOL implementsSelector = NO;
for (i = 0; i < count; i++) {
if (sel_isEqual(method_getName(methods[i]), aSelector)) {
implementsSelector = YES;
break;
}
}
free(methods);
return implementsSelector;
}
It's probably easier to check whether the method your own class returns is the same or different than the method your superclass returns.
if ([[obj class] instanceMethodForSelector:sel] != [[obj superclass] instanceMethodForSelector:sel]) {
NSLog(#"%# directly implements %#", [obj class], NSStringFromSelector(sel));
}
instance responds and super does not:
-(BOOL) declaresSelector:(SEL)inSelector {
return [self respondsToSelector:inSelector] && ![super respondsToSelector:inSelector];
}
instance responds and is different than super:
-(BOOL) implementsSelector:(SEL)inSelector {
return [self respondsToSelector:inSelector] && !( [super respondsToSelector:inSelector] && [self methodForSelector:inSelector] == [super methodForSelector:inSelector] );
}
According to Apple documents you should call respondsToSelector before methodForSelector.
You can use reflection to do that.