This question already has answers here:
Why should I use #properties? [duplicate]
(3 answers)
Closed 9 years ago.
Let say I have:
#interface test : NSObject {
BOOL bVal;
}
People keep saying properties are a better way of accessing a ivar, but are they doing it just for the heck of it?
Why would I need a #property for this ivar in this case?
I'm just wondering if people know why they are doing what they are told to, or if I'm missing something.
Properties get you some nice things, like synthesized getters and setters which are sure to be written in the best way for the property's retain/strong, assign/weak, atomic or non-atomic attributes. If you don't need code outside your class accessing the ivar at all then you should probably declare the ivar in the implementation itself and keep it completely hidden from the outside, like:
#implementation test {
BOOL bVal;
}
The answer to your other question is that it depends on the person, of course. Yes, there are plenty of people on this site parroting advice and code snippets without really understanding them. There are also plenty of people on here who really know what they're talking about.
Related
This question already has answers here:
Using self->ivar when accessing instance variables directly
(4 answers)
Closed 7 years ago.
So if I have in iOS (with Objective C, not sure if this the same for Swift) e.g.
#property (nonatomic, copy) NSString *aString;
And then some where in the code I have
// Simple ivar access in some method
_aString = anyStringOrNil;
// Self-> ivar access in some other method
self->_aString = anyStringOrNil;
I would like to know the differences between using one or the other
As you posted, those are identical. There is a difference between directly accessing the ivar and going through a property however. If you set the string as so:
self.aString = someString;
That would go through the automatically generated setter which, based on your property declaration would make a copy of someString. This is preferable in the case of working with mutable strings. You don't want the string to change out from under you. In both examples that you used, you are directly setting the value of _aString to the string reference, so if the string is a mutable string that is owned by someone else, it could change without warning and lead to unexpected results.
It is generally better practice to go through the setter (self.property = foo) rather than directly accessing the ivar as it is possible that the setter for the property has some behavior you may want and directly accessing it bypasses this. Of course, there are situations where accessing the ivar directly is required, but it is best to go through the property as a default.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm a student in a internship, and i'm learning Objective-C in order to develop an IOS application. They already had an existing base of code, but some part of the code give me problems.
As the previous developer isn't in the company anymore, and because no one else know about Objective-C, no one can answer some of my questions about how the application is built, so I can't determine if it is that i don't understand, or if it's just bad practices.
Here are these questions :
1°) In some classes, i found code like this :
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated] }
This code is useless, right ?
2°) In like 9/10 methods in the project, they return (void). Is it a common pratice in Obj-C (because everything is a pointer) ?
3°) Sometimes there is the interface declaration in both header and messages files. I guess it's because you want to declare only a part in header for a future include, and to have a "private" part. But in a file, i find the following code :
In header :
#interface WebViewController : UIViewController
#properties ...
#end
In Msg file :
#import ...
#interface WebViewController ()
#end
#implementation WebViewController ...
What's the point declaring a void interface a second time in the msg file ?
4°) More, in another class, the interface is declared a second time too, but a method is defined (in the msg file). What's the point as the method is defined bellow, and is not declared in the header file ?
thank you in advance
Welcome to Objective-C :)
Not necessarily. The super class may have specific behaviour defined in it's own method implementation that would cause an issue if you didn't call it. Overriding methods means the super classes own method won't be called by default.
Added from comment: Of courser if you didn't override it then the superclass definition would get called just fine. There are 2 common reasons why you would find it overridden:
a. It's in the Xcode template so it has always been there and not been removed
b.it used to have other content but it was deleted and the method call left behind.
Yes. Although you don't explicitly return void in the method, you do need to specify some return type. If you're not returning anything then void is the right value. It's found commonly in obj-c classes as the method may respond to being called by mutating an internal ivar or property and not require a return. Alternatively the result might be to send a notification so a return value is not needed. Increasingly the use of block-based completion handlers replaces explicit value return as a way to respond to the contents of a method.
Yes, it's to give a private interface that you don't want exposed. In the case where there's nothing in the private interface it's probably there because it came with the template code from Xcode and no one removed it. You can ignore or remove.
For the one you mention with a method, while it's not required to declare private methods in an interface it makes sense from the point of view of writing readable code (a strongly endorsed concept in obj-c). Since the compiler will remove any unnecessary code it makes no difference to declare it and makes the task of reading the code and understanding the class that much easier when you or someone else returns to it later. It's a also a good place to put documentation in comments as it groups it all together.
Hope that helps. Check out the Objective-C programming guides from Apple to for more best practice tips.
1). Yes you can delete this method
2). It depends upon your requirement, whether you want a return type or not. e.g.
- (BOOL)isEmptyOrNull:(NSString*)str;
3). These are called extensions, you can read more about it here http://rypress.com/tutorials/objective-c/categories.html
Extensions are used to hide the methods from out side world(by saying hide I mean you can't find those methods with your eyes)
4). Methods define in implementation file are not visible to a programmer, it's just like private methods in java but in ObjC there is no such thing like private method. Read this thread for private methods Best way to define private methods for a class in Objective-C
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 8 years ago.
I am new to iOS development, but this is a question which I have a lot of trouble with and could help others.
I need to pass a simple integer variable between two views. This is an example of a variable I need to pass:
int tally = 1;
People talk about messing with delegates and protocols to pass data between views, but frankly, that is all a bit over my head. Is there an easier way to pass simple variables such as integers between two view controllers?
Thank you kindly for any responses!
#interface View1:UIView
#property int passingInt;
#end
#interface View2:UIView
#property int passingInt;
#end
Now, you can directly set the variables like,
view1.passingInt=view2.passingInt;
or
view1.passingInt=100;
Although these are not the correct ways to do this kind of stuff I'll give you two different methods.
Create a global variable in a class header file, say CommonVar.h.
You can now use this variable with anything that has this header file imported
//CommonVar.h
int foo;
//This is the entire file
Now if you import this file in any class, you can use foo directly.
The other method is to use singletons and their variables. You can read about them here http://www.galloway.me.uk/tutorials/singleton-classes/
I am telling again this is not the correct way to do this but I think you will find them simple than handling delegates.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm following the Stanford Developing iOS 7 course 2013 2014 on iTunes U (just for your info) and I'm having some general questions on the Objective C language. Thanks for your help!
Question 01
This is what I understood about #synthesize:
With the newest versions of Xcode there is no need to perform #synthesize for declaring a setter or a getter. It is done automatically for the programmer if the getter and setter is kept at default. However I have been taught I need to declare the synthesize when overrides BOTH the getter and the setter.
My question is: why only when BOTH are being overriden? It should make more sense to me you would need to declare the synthesize already when only one needs to be overridden?
Question 02
- (void)addCard:(Card *)card atTop:(BOOL)atTop;
- (void)addCard:(Card *)card;
Are 2 different public methods used in the course I'm following.
Question: Am I required to state these two as 2 individual methods. Couldn't I just use the first one, whilst specifying 2 different blocks of code to perform, by an IF ELSE clausule whether the BOOL is YES or NO? Wouldn't that be exactly the same outcome?
Question 03
Having a rather simple program with just a single view, I noticed I do not need to publicly specify any methods in my viewcontroller.h. I reckon this only would be needed if your program is more complex and contains several MVC where the controllers would need to "speak" to each other. Is this a right assumption to make, generally speaking, when making a proper MVC based program?
I thank you for your time and effort. Excuse me if my questions seem basic or do not make complete sense. I'm on the iOS learning path stage 1, with little OOP experience.
Question 1:
You are right about this. If you override the getter and setter then you need to #synthesize the property. I'll have to have a further look for why though.
Question 2:
Yes, you could just have the first method. However, the second method is there as a convenience and would normally contain code something like this...
- (void)addCard:(Card *)card
{
[self addCard:card atTop:YES];
}
Then the designated method would do something like...
- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
if (atTop) {
// something to add card to top.
} else {
// something to add card at bottom.
}
}
i.e. it just routes the method call to the "designated" method but uses a default value for the BOOL.
Question 3:
The .h file is there as an interface file. It would be similar to a set of web services on a server. The class can do all sorts of stuff internally but it only needs to declare stuff in the .h interface file if something needs to access them externally.
For instance, you might have a class called Car. It might have a button called accelerator that would access an internal method and increase the speed. None of this needs to be exposed to external classes.
However, the same car might have a property called colour or a method called addFuel. These would need to be available externally so the user can see the colour and add fuel. These both need to go in the .h file.
I hope that makes sense.
Question 1: I have been taught I need to declare the synthesize when
overrides BOTH the getter and the setter. My question is: why only
when BOTH are being overriden? It should make more sense to me you
would need to declare the synthesize already when only one needs to be
overridden?
Once you use #synthesize you are using the setter/getter provided by the compiler. If you create your setter/getter without synthesize then you need to write both the methods, if you have readwrite property.
Question 2: Am I required to state these two as 2 individual methods.
Couldn't I just use the first one, whilst specifying 2 different
blocks of code to perform, by an IF ELSE clausule whether the BOOL is
YES or NO? Wouldn't that be exactly the same outcome?
Yes it is good to have two different methods. As these two vary on the parameters and the caller will know what is happening inside the method. If you wish to put if-else, for this you will require an ivar or a global value to check, but if you pass the BOOL no need for it.
Question 3: Having a rather simple program with just a single view, I noticed I do
not need to publicly specify any methods in my viewcontroller.h. I
reckon this only would be needed if your program is more complex and
contains several MVC where the controllers would need to "speak" to
each other. Is this a right assumption to make, generally speaking,
when making a proper MVC based program?
Even though you don't have any complex but always follow the architecture of MVC.
The controller in iOS programming usually refers to the view controllers. Think of a view controller as a bridge between the model and your views. This controller interprets what is happening on one side and uses that information to alter the other side as needed. For instance, if the user changes some field in a view, the controller makes sure the model changes in response. And if the model gets new data, the controller tells the view to reflect it.
Question 01
(edited) You need #synthesize to tell the compiler to create the ivar (eg. _myString) for you. You could also declare the ivar manually.
Question 02
You could just declare the first one yes. In fact the second one just a shorthand method, providing a default value for atTop. In most cases, you would implement the method exactly as you explained:
- (void)addCard:(Card *)card atTop:(BOOL)atTop {
if (atTop) {
// atTop == YES
}
else {
// atTop == NO
}
}
- (void)addCard:(Card *)card {
[self addCard:card atTop:YES]; // or atTop:NO, depending of the default value you want to use
}
Question 03
Again, yes. Your view controllers should expose as little properties and methods as possible, and make public only things that should be available for the rest of the application to use. So in the case of the single VC / single view program, having an empty VC interface is normal.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I know iOS Runtime is powerful and I have a question: where should we use runtime?
For example, I find many articles will discuss about class & method swizzling. And in which case should I use it?
I also google it and find it is widely used in jailbroken development. However, I'm a non-jailbroken developer, please don't cover jailbroken~
Thanks!
It's a very general question. The runtime is a library linked with your programs that implements part of Objective-C so it may show up anywhere. If you have to ask, don't use it. But FYI here are some common uses:
Swizzling
Swizzling is the exchange of the identifiers of two methods so they point to each other’s implementations. Both methods are still available.
It's useful to use swizzling instead categories to preserve the original implementation of the method, and to avoid having two categories overriding the same method (the result would be undefined).
See https://stackoverflow.com/a/8636521/412916 for a list of dangers.
Dynamic methods (sort of)
See https://stackoverflow.com/a/13646650/412916
Associative references
An associative reference is a way to add an instance variable to an object without changing its code. The associative reference is automatically removed when the object is deallocated.
Google it.
Introspection
Introspect the properties of the classes. For example to map between JSON and a plain class of your model. I guess Mantle and the Overcoat wrapper are examples of this.
You should read the Objective-C Runtime Programming Guide.
Using emoji as a method name
This is probably the most important use. The code is not mine and I don't remember the original author.
#include <objc/runtime.h>
#import <Foundation/Foundation.h>
#interface A: NSObject
#end
#implementation A
void pileOfPoo(id self, SEL _cmd) {
NSLog(#"💩");
}
+ (BOOL)resolveInstanceMethod: (SEL)name {
if ([NSStringFromSelector(name) isEqualToString: #"💩"]) {
class_addMethod([self class], name, (IMP)pileOfPoo, "v#:");
return YES;
} else return NO;
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool {
A *a = [[A alloc] init];
SEL aSelector = NSSelectorFromString(#"💩");
[a performSelector: aSelector];
}
return 0;
}
Generally it shouldn't be used. When it is used it should be done with great care as the risk of breaking everything is high when you make a mistake. Usually it should only be done in well used code, preferably maintained as an open-source project so that many people check the validity.
It's not only used for jailbreak, but it does generally involve private classes / methods and allows you to workaround / expand limitations in the APIs. But it can also be used to expand by, for example, inserting your own class as an observer in some relationship so it can take some action and then forward the information to the 'true' observer (AFNetworking used to do this).
Generally you should use features like categories or standard subclasses to add functionality.
Method swizzling in runtime is a good measure to 'hook' methods whatever you want. Why do we need hooking? There are all kinds of application of hooking, such as user behavior statistic, automatic serialization and so on.
Here we take user behavior as a sample. With help of method swizzling, we can hook 'viewWillAppear' method in any UIViewController subclass. That means we can know when 'viewWillAppear' is called and thus we can inject user behavior codes(e.g. page visiting count, page visiting duration) before or after 'viewWillAppear' method. In summary, with help of method swizzling, we can easily make user behavior statistic realized. Other kinds of application are the same.