issue with custom delegate and datasource - iphone

I have a custom delegate and datasource. But I have several problems with it when I try to initialize it. In my .h file if have it like this.
#property (nonatomic, assign) id<UITableViewDelegate> delegate;
#property (nonatomic, assign) id<KalDataSource> dataSource;
This has as an result that in the synthesize in the .m file I get the following error.
Existing ivar 'dataSource' for property 'dataSource' with assign attribute must be __unsafe_unretained.
After some google search magic I found that I should assing my variables like this.
#property (nonatomic, strong) id<UITableViewDelegate> delegate;
#property (nonatomic, strong) id<KalDataSource> dataSource;
But then I get this error.
linker command failed with exit code 1 (use -v to see invocation)
Can anybody help me with this?
Kind regards!

The error you're experiencing has nothing to do with your memory qualifiers (they were right the first time around). The problem lies in the fact that you have declared a backing iVar somewhere without qualifiers. When iVars are declared, they are implicitly strong, so if you go to your shadowing iVars, and prepend __weak or __unsafe_unretained, the warning should disappear. Of course a better solution would be to just remove your backing iVars altogether, because Xcode will synthesize them for you.

Delegates are usually weak references.
The object using the delegate doesn't own it.
It's just a reference to an object which could, or could not be responding.
Weak says, that if the real owner of the object releases it, it should be deallocated.
The weak reference is then automatically set to nil and you don't get any zombies.
Second, the problem is, that you already have property called dataSource.
EDIT
My previous statement about the duplicate property turns out to be wrong.
You should override the setters & getters, both the declaration in the .h and the implementation in the .m file.

Related

objective-c interface - declaring variable vs just property?

In Obj-c when declaring a variable within #interface
#interface: NSObject{
MyObject* myObject}
#property (unsafe, nonatomic) MyObject* myObject;
Vs. Only declare it as a property
#interface: NSObject{}
#property (unsafe, nonatomic) MyObject* myObject;
#end
Not declare any var here?
Regards
Christian
#property defines an interface, not an implementation. In your case, you're defining a readwrite property. This means that you're promising to implement -myObject and -setMyObject:. This has nothing to do with ivars.
Now, the most common way to implement those methods is by having them be backed by an ivar. As a convenience, ObjC lets you automatically generate the required methods with an ivar store using #synthesize myObject=myObject_; This says "create the required methods for the property myObject using an automatically created ivar called myObject_." The ivar myObject_ is a real ivar, and you can access it normally (though you generally shouldn't; you should use accessors).
Instead of using #synthesize, you could just implement -myObject and -setMyObject:. You could even use #dynamic myObject; to tell the compiler "don't worry about the implementations for this property; it'll be handled correctly at runtime."
There are a few differences between #property and just declaring methods, but in principle, this line:
#property (nonatomic, readwrite, strong) MyObject* myObject;
is conceptually the same as this:
- (MyObject *)myObject;
- (void)setMyObject:(MyObject *)anObject;
Declaring the ivar yourself has no real impact here. You still need to implement the methods somehow. If your named ivar is the same as the ivar #synthesize is using, then #synthesize just won't create a new ivar.
As a matter of practice, I discourage people from declaring ivars anymore. I recommend just using public and private properties with #synthesize to create any needed ivars. If you must have a manual ivar for some reason, then I recommend declaring them in the #implementation block rather than the #interface.
Skipping declaring the ivar is perfectly fine--but you will not be able to see the ivar's value in the Xcode IDE. One day Apple may fix this.
You will be able to "po" the ivar to inspect it in GDB or lldb.

Private properties and methods in Objective-C

In looking at one of Apple's examples, in the TableViewController.m, they have this:
// Private TableViewController properties and methods.
#interface TableViewController ()
#property (nonatomic, retain) NSMutableArray* sectionInfoArray;
#property (nonatomic, retain) NSIndexPath* pinchedIndexPath;
#property (nonatomic, assign) NSInteger openSectionIndex;
#property (nonatomic, assign) CGFloat initialPinchHeight;
... more properties and methods
#end
#implementation TableViewController
... usual stuff
I'm wondering why they put these properties in the .m file and how this is private. It seems like anyone who imports the TableViewController.m file can use these properties and methods right? Why not use the #private in the .h file?
What they're doing is declaring a category on the class, but since this is done in the .m file, the effect is that those methods are "invisible".
This doesn't mean however that those methods cannot be called from the outside. This is due to the fact that there is no real privacy in objective c, because we're dealing with messages, not method calls. This means you can send an object a message even if you do not know if that object actually implements the method you're trying to call. The receiving object will determine at runtime if it can handle this call, maybe it will even forward it, and it will make no difference whether the method was known to the calling object or not.
This is one of the reasons why it is possible to call private APIs and get rejected for it.
They're not private. They're anonymous properties, since they're part of an anonymous category.
One of the things properties are good for is putting the memory management semantics for an owned object in a single place. Consider this:
#property (nonatomic, assigned) NSString *assigned;
#property (nonatomic, copy) NSString *copied;
#property (nonatomic, retain) NSString *retained;
In all three cases, you can assign to them like this without knowing what their memory semantic is:
self.assigned = stringParameter; // assigns to instance variable
self.copied = stringParameter; // copies, assigns copy to instance variable
self.retained = stringParameter; // retains, assigns to instance variable
And in all three cases, you can free clean up using the same code:
self.assigned = nil; // this just nils the instance variable
self.copied = nil; // releases copy in ivar, nils instance variable
self.retained = nil; // releases ivar (same as original object),
// nils instance variable
This is why you'll often see local properties: It lets the coder skip writing all the memory management logic each time they want to assign to the instance variable. This is a major advantage in that you can change the memory management logic throughout the entire class just by changing the #property.
Another use of anonymous properties is to extend a property declared as readonly to outside code as read/write to the class itself.
In .h:
#property (nonatomic, readonly, retain) NSError *lastError;
In .m, in an anonymous category:
#property (nonatomic, readwrite, retain) NSError *lastError;
Elsewhere in .m code:
self.lastError = error;
Again, this is mostly done for memory management reasons.
An example, that pertains to either use of anonymous properties.
Here's what each assignment to a _lastError instance variable looks like without properties.
Assume we have a NSError called _lastError defined in the .h file.
With retain:
[_lastError release];
_lastError = [error retain];
With copy:
[_lastError release];
_lastError = [error copy];
With assign:
_lastError = error;
In the first two cases, you need this in your dealloc:
[_lastError release];
But in the last case, you must put nothing in the dealloc or you'll get a crash.
So let's add what we need to use a property instead:
Add this in an anonymous category:
#property (nonatomic, readwrite, retain) NSError *lastError;
Add this in the #implementation:
#synthesize lastError = _lastError;
Note, also, that at this point on the "modern" Cocoa runtime (64 bit Mac or iOS), you can remove the NSError *_lastError from your header. The compiler can figure out you want that based on the #synthesize.
Here's how that changes our code:
Each assignment:
self.lastError = error; // works regardless of storage specifier
In daelloc:
self.lastError = nil; // works regardless of storage specifier
AFAIK
a) You can not mark properties as #private in .h - this works only for ivars.
b) You will not be able to reference your class if you just import .m file (without interface definition in .h file). and if you do - you will get duplicate symbols during linking.
c) So yes these properties are private in the sense they are not accessible as regular properties from outside - these properties are accessible only using explicit messages - however you'll get warnings from compiler in this case or you could use KVC
First, you typically cannot import an .m file - not without numerous compiler/linker errors. Second, the properties are private so that Apple is free to change them in subsequent releases.
Yes, you can get to them via reflection. But that's a slippery slope, blah blah proceed at your own risk, will break in later versions blah blah reflection bad unless you know exactly what you're doing.
There are no private methods or variables in objective c, the #private flag is mainly there just so when other developers look at it, they know it's supposed to be private. What your seeing in the apple code is an example of a category, a way to fake private methods and variables in objective c. Because outside classes will import the .h file only, they will never see the added methods and variables in the .m file.
Using an anonymous category black boxes internal properties and methods that other classes should not know about. Although the compiler doesn't know about them when this class is referenced from other classes, you could technically access any of these properties from that other class using key value coding.
you can't import the implementation file TableViewController.m, Only the .h file of TableViewController could be imported,
Although, you could have the reference of these property outside your TableViewController class with a warning that shows the "not respond" note.

Instance Variable Syntax Question

When declaring an instance variable, does it make a difference if I declare it under #interface and as a #property? Example:
#interface MyViewController : UIViewController {
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
Would it matter if I took out the one under #interface? I have been doing that and would like to know if it does anything.
With a modern compiler (recent versions of LLVM), there is no need to declare the instance variables in conjunction with an #property (as tc says; it is the #synthesize that actually tells the compiler to reserve a slot, otherwise, you are on your own for storage) and doing so doesn't change anything.
One suggestion; when you #synthesize, do something like #synthesize myString = myString_; to cause the iVar to have a different name and, thus, make it impossible to accidentally directly access when you meant to go through the property.

Question on UIApplicationDelegate generated by Xcode

I'm trying on objective-C and Xcode 4, and get some bit I don't understand.
The following code are generated by the Xcode for a view-based iphone application:
In the .h file:
#interface viewexampleAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet viewexampleViewController *viewController;
#end
In the .m file:
#synthesize window=_window;
#synthesize viewController=_viewController;
So the question is:
where is the _window and _viewController comes from? I didn't see any declaration or initialization of them.
Objective-C allows declaring properties without having to explicitly declare the corresponding backing instance variables. Instead, instance variables are synthesized as needed. In this case, by default the name of the backing instance variable is the same as the declared property name. So, assuming the class hasn’t declared an instance variable called something,
#synthesize something;
would implicitly create an instance variable also called something.
It is also possible to have the instance variable be named differently from the declared property, e.g.
#synthesize something = _something;
The compiler then creates a backing instance variable called _something in case one doesn’t already exist.
With regard to initialisation, both properties are IBOutlets. This usually means that their corresponding instances are loaded from a nib file, and the nib file has outlets connecting those properties to actual objects.

Help: Instance Variables & Properties [iPhone]

In something like this:
#interface Control_FunViewController : UIViewController {
UITextField *nameField;
UITextField *numberField;
}
#property (nonatomic, retain) IBOutlet UITextField *nameField;
#property (nonatomic, retain) IBOutlet UITextField *numberField;
I understand that "UITextField *nameField;" is an instance variable and "#property ..." is a property. But what do these individual things do?
I guess what I'm really asking is how the property is used for example in the implementation file (.m)
The instance variables are the actual variables, whereas the properties are the equivalent of
- (UITextField *)nameField;
- (void)setNameField:(UITextField *)newTextField;
and completely optional. They are also used by the compiler to understand exactly what you want when you #synthesize a variable. Basically the properties and corresponding #synthesize (or custom implementation) allow OTHER classes access to variables, and are completely optional. It is in fact generally recommended, as per standard object oriented encapsulation principals, not to use properties unless you specifically intend for them to be used by external classes. However, you still need Interface Builder to recognize the UITextFields (presumably) which is why we typically put the IBOutlet decorator before the ivar declaration, not the property.