ios - creating functions - iphone

I know what a function is, but I am trying to write a few into my project. I have just watched a video series on Objective-C from Lynda.com where I got the idea from.
In the video is it is explained that I can write a function like this:
void declareWebView ()
However if I write it like that into my code, the error comes up and says that my _webView and self (as self.view) are not available.
if I write it like this:
-(void) declareWebView
Then I do not have an issue.
Any ideas on how to get the first one right?
As far as I can tell, I cannot set any parameters with the second way of writing.

The first is as you said called a function. It is part of the C part of Objective-C, and is not connected to objects or classes, so the variable self or any instance variables of an object don't have any meaning. You can pass it variables that are objects though like so:
void my_func(NSString *string, id someObject, int someInt);
void my_func(NSString *string, id someObject, int someInt)
{
NSLog(#"string = %#, someObject = %#, someInt = %d",string,someObject,someInt);
}
The second is a method, and in a method you can access self and, within instance methods, access instance variables. Replacing the "-" in front of the method with a "+" makes it a class method. In a class method you can't access instance variables and self refers to the class itself, not an instance.
Hope this helps!

The first way is written in the language C. The second way is written in Objective-C. Objective-C methods must be declared the second way. You cannot access your object's private members and properties from within a C function directly, but you could use accessor methods on the Objective-C object and call them from a C function.

Related

arrow operator in swift

I am trying to adopt a SDK written in objective-c in a swift project. The objective-c way to initialize the SDK is as follows:
#implementation ViewController
nokeSDK *nokelock;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//INITIALIZE NOKE SDK
nokelock = [[nokeSDK alloc] init];
nokelock->cmd = [[nokecommand alloc] init];
I don't believe there is an equivalent to the arrow operator in swift, so is it possible to still initialize? I can't seem to find any info about his particular subject.
In Objective-C, a property is merely syntactic sugar for accessor methods; if, as is usually the case, these are a front for an instance variable, you can, with the right privacy access, bypass the accessor methods (or not have them in the first place) and get/set the instance variable directly. That's what your code is doing.
But Swift doesn't draw that distinction. A variable declared at the top level of a type declaration, in Swift, is a property; behind the scenes, a stored property has accessor methods, and you are passing through those automatically when you get/set the property. There is no separate instance variable to get/set.
To see what I mean, make a hybrid Swift / Objective-C app with class Thing whose interface looks like this:
#interface Thing : NSObject {
#public
NSString* s;
}
Now create the generated interface. You will see that, in Swift, s is nowhere to be seen.
Presumably, therefore, to rewrite your code, you'd need to turn cmd into a property, or at least provide a setter method. Otherwise, Swift will never be able to set the Objective-C cmd instance variable. Of course, if it is also up to you to rewrite nokeSDK in Swift, your problems are over, as you can now do whatever you like.

How to check what class was an object initialized in Objective C

Is it possible to check and get the name of the class an object was initialized in?
Example: I have Class A. I created object ABObject using [[ABOBject alloc] init]; via an instance method.
How can I find out the class from which an instance ABObject was created, namely "A" here?
Objects can be created outside the context of a class, so it wouldn't make sense for this to be a built-in language feature.
If you do have to do this, one way to work around it would be to use the objc_setAssociatedObjects() function in objc/runtime.h immediately after any such object was instantiated. Something like:
ABObject *object = [[ABObject alloc] init];
objc_setAssociatedObject(object, #"InstantiatingClassKey", [self class], OBJC_ASSOCIATION_ASSIGN);
Then you could get it with objc_getAssociatedObject(object, #"InstantiatingClassKey").
I think you'd be better off re-assessing your design because this is not going to be particularly maintainable. Even extracting this into a category on NSObject to remove duplicated code you'll still have an extra step to remember and weird relationships between your objects.
Also, as Martin R. points out in the comments, I'm taking a shortcut and passing a string literal as the key argument for the function, in reality you'd want to follow the practice of using the address of some static or global variable.

simple method returns in objective c

I am currently new to objective c and have came across a problem while making a game I have a custom made object called battleEngine which is an instance variable in my helloWorld scene in cocos2d. That object has an object as an instance variable called plyController which is a PlayerController object. I want battleEngine to have a getter method that returns the plyController object and this code doesn't work:
-(PlayerController*)getPlayerController
{
return plyController;
}
Is there any reason you haven't just declared your player controller object as a property? You could just use the synthesised getter in that case to get the player controller.
Have a look at the documentation on properties.
Also, and I'm afraid I have to say this or they will take my Cocoa-programmer badge away from me, getPlayerController is not a good method name. Methods with get in them are conventionally used to return values in the parameters passed in by reference. The Cocoa Coding Guidelines tells us this, and much more.

Good practice for disambiguating argument names versus instance variable names in Objective-C

I run into a fairly common scenario in Objective-C where I pass in a variable to an init method and then want to assign it to an instance variable of the same name. However I have not found a way to scope the variables to clarify which is the value from the message argument and which is the instance variable.
Say I have some class such as the following:
#interface MyObject
{
NSString *value;
}
- (id)initWithValue:(NSString *)value;
#end
In my implementation I want my init method to look something like this:
- (id)initWithValue:(NSString *)value
{
self = [super init];
if(self) {
self.value = value; // This will not work with instance variables
}
}
I know of three solutions:
Create a property, which allows calling self.value
Rename my instance variable, such as _value
Rename my init argument variable, such as initValue or argValue
I am not pleased with any of these solutions. Adding a property either makes the property publicly available on the interface or, if I use an extension, hides it from inheritors. I also do not like having different names for the variables or using an underscore, which perhaps comes from developing in other languages such as Java and C#.
Is there a way to disambiguate instance variables from message arguments? If not, is there a coding guideline in Cocoa for how to solve this problem? I like following style guidelines when appropriate.
Update
After thinking about how to do this in C, I came up with the solution of self->value. This works, but it produces a compiler warning that the Local declaration of 'value' hides instance variable. So this is not a satisfactory solution either since I have a zero-warning goal.
For setters (and by extension initializers), I believe the convention is to prefix the parameter name with new:
- (void)setCrunk:(Crunk *)newCrunk;
- (id)initWithCrunk:(Crunk *)newCrunk;
In general, I think the most common form I've seen is to call the parameter theCrunk, but Apple seems to recommend aCrunk.
And changing the name to "inValue" is not a good idea? What you have here - your 'solution' is complex, especially with the accessors, etc of Obj-C 2. Since self.value and inValue are different things, they need different names.
Note that you can use
-(void)method1:(NSString*)value;
in the header
and
-(void)method1:(NSString*)inValue;
in the .m file.
If you use only 1 the compiler will give you a warning.
You can combine 1 & 2 by using :
#synthesize value = _value;
If you want to hide your variable from the inheritors you can declare a empty named category and declare your property there.
For 3 you can use aValue for your argument.

vs [mpk5 weaponAttachments]

I'm able to make the method for the call [self weaponAttachments:mpk5] but I don't like having to call self. I think [mpk5 weaponAttachments] is more natural and is easier to read.
The problem I'm having is I need to pass in the weapon (mpk5) in order to use it, which I can do with the first method but not with the second one. Does this mean that I need to subclass NSDictionary in order to be able to use a statement like [mpk5 weaponAttachments]? If so, how do I get ahold of the caller "mpk5" so that I can use it inside the method?
EDIT
I apologize for not putting this in the first time but my objective is to have [mpk5 weaponAttachments] return an NSDictionary or NSArray. Right now I have NSDictionary *attachments = [self weaponAttachments:mpk5]; which works but it just doesn't seem like the best approach.
So firstly, your two calls are a little mixed up:
[self weaponAttachments:mpk5] calls the weaponAttachments method, passing in the variable mpk5.
But [mpk5 weaponAttachments] is either asking the mpk5 object to return the weaponAttachments property or is asking the mpk5 object to run a method called weaponAttachments (I'm simplifying here - it's always a method, but if you're using properties you probably won't realise this as Objective-C will create them for you).
These are fundamentally different things.
On to the brunt of your question:
I don't like having to call self
...unfortunately, if you're working in an object-oriented language you're going to have to get used to this. Say I have a class called mySimpleClass, and a method inside that class called doSomething. Writing this:
[mySimpleClass doSomething] would be what we call a static method. Whereas calling [self doSomething] from within an instance of mySimpleClass would be an instance method.
If you're unsure of the difference between static and instance methods you should probably step back and take a look at some of the basic guides out there.