what can be possible reason for error "statically allocated the instance of objective c class uitableview" ?
Please read the ObjC Programming Guide;
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html
Or you could just fix it via
MyClass *foo = nil;
instead of;
MyClass foo = nil;
notice the * character, its important. To find out why you really need to read the docs.
Guess it means that there is a variable that is globally scoped or class member and you declare that variable again in a lower scope.
Related
Actually I am from java background and I am learning objective c.I am very confused about strange behaviour of objective C."Please Read 3rd Question its important one."
Questions are provided in sequence so please give answers in sequence as its understandable to me and others.
Question 1
I have two classes derived from NSObject: A and B:
#interface A : NSObject
#end
#interface B : NSobject
-(void)display; // It displays "I am class B"
#end
Now if I do this:
A *a = [[B alloc]init]; // Show warning not error (it must be illegal)
[a display]; // prints "I am class B"
It calls the display method of class B. I don't think that it should happen because:
A doesn't have the method display. By polymorphism.
This could be a security threat as I am creating reference of any class and passing object of any another class and accessing data by it.
There could be design issues as Dog class instance gets an object of Printer class and now i am calling print method on Dog instance.
I have reference of NSArray and passed object of NSMutableArray and now i am calling NSMutableArray method on this instance.
[nsarr addObject:#:abc]; //Looking very odd
Question 2
If I have Foo protocol and if any class is not confirming it. It should not be allowed to get object of that class in protocol reference.
#protocol Foo
#required
-(void)abc;
#end
If i call:
id<Foo> obj= [[B alloc]init]; // Shows warning ignore it for now as it must be illegal also
[obj display]; // It will call display method which should be illegal
It should not happen, as B is not conforming to protocol Foo and obj is taking B object and calling B instance method. I think its very bad because of polymorphism and security
Question 3
If my class has a class method which returns an object of that class which is not autoreleased, the compiler shows warning. If I pass the object returned by that class (not conforming protocol) method to reference of protocol. (IT SHOULD BE AN ERROR).
id<Foo> obj = [Abc aClassMethodReturnsObjectWhichNotAutoreleased]; //show warning
It shows a warning which is good. Abc did not conform to the protocol Foo
BUT
id<Foo> obj = [NSArray arrayWithObjects:#"abc",#"def",nil]; // It does **not** show a warning as it will return autorelease object. NSArray doesn't conform protocol Foo
Why does the above assignment to the NSArray class not show a warning as it is showing in the previous example.
Thanks in advance.
EDIT
*Answer 3rd Question:*As NSArray returns id object which will allow to pass in "id obj" but in "aClassMethodReturnsObjectWhichNotAutoreleased" case the method returns "ABC *" pointer so that is why compiler giving warning in this case.
Question 1:
A *a = [[B alloc]init]; //Show warning not error (it must be illegal)
[a display]; //prints "I am class B"
Here you are using a static type A for the variable named a. You are then assigning a different type of object (B) to the variable.
Unlike java, Objective-C does not enforce the static typing requirement, however it does warn you when it is being compiled since the compiler detected a difference between the declared type and the actual type of the object. It happily stuffs the B object into your variable though, so a is now pointing to the B object that you created. Once the program is compiled and running (at run-time), A *a is treated the same as id a.
Another feature of Objective-C is that you can send any message to any object at any time. This is part of the dynamic nature of Objective-C. Obviously there are cases where sending the wrong message to an object can cause bad things (tm) to happen so you need to ensure that you only send appropriate messages. There are various functions that can test the class of an object at run-time, or even test to see if it is able to handle a particular message before you send it in order to prevent the bad things. If you are using static typing (like in this example) then the compiler will issue warnings to tell you that you may have made a mistake and should review the code.
Question 2:
This is actually very similar to question 1. The compiler is warning you that you are assigning what appears to be an incorrect value to the variable, however at run-time you can send any message to any object, so it will work on the actual object instead of the "expected" object from the type declaration.
Question 3:
Good question. I would have thought that you would get a warning there too. Maybe someone else can help out on that. My first thought is that this is a bug and should be reported as such, but there may be a reason for it that I'm not aware of....
Objective-C and Java have very different type rules, as you have discovered.
Java is strictly statically typed, which means that types must match, and you can never make an assignment that is not allowed by the type conversion rules.
Objective-C is dynamically typed with optional static types. You can break out of the type system at any time. For some cases, the compiler will emit warnings, but it is still allowed.
This is the reason why you are seeing the behavior. Objective-C is not broken, it just have different rules than the ones you know from Java.
Apple has a lot of documentation of the specific rules, perhaps you would want to read Enabling Static Behavior.
Here are some more resources about dynamic vs static typing for you:
Dynamic type languages versus static type languages and What do people find so appealing about dynamic languages?
A *a = [[B alloc]init]; //Show warning not error (it must be illegal)
[a display]; //prints "I am class B"
Because you initialized variable from B class that have display property.
It's correct
I'm learning Objective C to program on iOS.
I know it has something to do with pointers, which I fail to understand.
I don't know what's the difference of creating a string (or any NSObject) like this:
NSString place = ...;
or
NSString *place = ...;
Thanks for the help!!
You never write NSString str. Period. All Obj-C objects are actually C pointers.
NSString is a class and as such instances of the class declared as NSString *str must always be declared as a pointer (since object instances can only be accessed via a pointer to the objects structure). Therefore this declaration is illegal: NSString str
Objective-C is, in some sense, more like a scripting language. Class definitions are maintained during runtime and can be modified. There is a C interface to the class definition system in objc.h. Even system classes can be modified, though it is not a good idea to do so. Because of this, all Objective-C objects must be created at runtime and accessed via pointers. To put it another way, there is no way for the compiler to know what an object should look like at compile time. This is also why "object may not respond to selector" is a warning, not an error and has the word "may" in it.
I noticed a difference between the way I code (badly ;) ) and the code I see from others.
Can anybody explain why I see some people using
self.varname.anotherpropertie
When
varname.anotherpropertie
Seems to work just as well. I dont use self. a lot in my code. I'm wondering is this very bad or is there something that I need to learn to understand why its used so much by most people?
Thanks again,
-Code
They are different things. In a class where you have an instance variable named foo with a declared property also named foo, writing simply foo accesses the instance variable while self.foo goes through the getter method for the property (which might just return the instance variable or it might do more).
I'd suggest taking a look at the Declared Properties chapter of Apple's The Objective-C Programming Language for a full explanation of how it works and when to choose which option.
One gotcha that I've run into is the retain vs non-retain with properties.
So if you have a retained property like this:
#property (nonatomic, retain) NSString* myStr;
#synchronized myStr;
and you do something like this:
- (void) myMethod:(NSString*)inStr
{
myStr = inStr;
}
In this example you will not actually retain the string as your property is not invoked. If you change the assignment line to use the property (by using "self.") then the string would be retained (and the previous string would be released if non-nil).
self.myStr = inStr;
It takes some getting used to that properties are method calls, but once you start seeing them as such then the "self." syntax becomes much more clear. Hope that helps some.
How do I use global variables in x-code(iphone). For example, lets say i want to declare a bunch of variables(NSStrings) in the viewcontroller file, then how would i access them throughout my different classes? Can someone help me?
Global variables are global variables. You use them the same way you would in any C program, which is to say typically they'd be declared in something like "globals.h" and imported wherever needed.
With that said, it's generally poor practice to rely on globals. You might have an "ApplicationController" object which in essence tracks the global state of the application, but its variables should be instance variables and either accessed only internally, or via getters/setters.
If you wanted to declare a bunch of strings in a single object to be referenced by many other objects, typically you'd make that object a Singleton and pass a reference to it to each object needing access to it.
However, you need to ask yourself WHY you need to do that and if there isn't a better way. I'll bet dollars to doughnuts there's not a good reason for what you're trying to do.
Give us some more details on what the overriding need is for these strings to be global, and then we can show you reasons why they don't. :)
You may use a singleton if it's not too over-killed. Another option is NSDefaults. Of course, the simplest way is simply define an extern in .h
extern NSString * const STR_1;
and the value in .m:
NSString * const STR_1 = #"String One";
just declare your variables in the .h file and then import this file in any class you want to use it. You can make any type of object or variable global.
If you declare the variable in delegates, You can access those variable in any other controllers using setter and getter methods to access.
See Warrior Answer
I hope,it will help you.
I noticed that I rarely use properties, due to the fact that I rarely need to access my object's variables outside my class ;)
So I usually do :
NSMutableArray *myArray; // not a property !
My question is : even if i don't declare myArray as a property, does iphone make a retain anyway if I do
myArray = arrayPassedToMe;
I think so but I just wanted to confirm ;)
Any thoughts welcome !
Gotye
If you do not declare a property with 'retain' then no retain call will be made. It is generally preferable to use the property accessors (for all cases, it makes memory management much simpler), however you can perform a manual retain as such:
myArray = [otherArray retain];
Just to add to Kevin's answer, in this case you also need to make sure that any existing object at which myArray is currently pointing is freed before you assign new value to it, which means:
[myArray release];
myArray = [otherArray retain];
When you access your class variables via declared properties, all this stuff with retaining/releasing memory is done for you automatically, making your life much easier.