Swift: dynamically creating and assigning delegates - swift

MKMapView's delegate property is defined as so in swift:
#IBOutlet weak open var delegate: MKMapViewDelegate?.
If I had to dynamically create map views for each item in an array whose length/count is unknown beforehand, how I dynamically assign a unique delegate instance to each one of the maps without keeping a class variable for each delegate (since we don't know the count of items in the array). Is there something similar to Obj-C's __Strong ?
Update:
I could have a class array to which I add each delegate, but still, are there any other approaches, which are more inline for example by using __Strong, if there is such a thing in Swift

how I dynamically assign a unique delegate instance to each one of the maps without keeping a class variable for each delegate
There's no need for a unique delegate object for each map view. Delegate methods typically get a reference to the delegator as their first parameter, so the delegate can easily tell which map view is sending the message.

Related

Swift: How to define a UIView delegate with unowned(unsafe) reference?

I find the following code in UITableView class,
unowned(unsafe) var delegate: UITableViewDelegate?
so I wander how to define a unowned(unsafe) reference delegate for UIView, then I encounter the following error when I write the unowned(unsafe) keyword in my class,
/Users/larryhou/Documents/Xcode/AtomicElements/AtomicElements/AtomicElementView.swift:32:25: 'unowned' cannot be applied to non-class type 'AtomicElementViewDelegate?'
protocol AtomicElementViewDelegate:NSObjectProtocol
{
func didTap(target:AtomicElementView, sender:UITapGestureRecognizer)
}
I can only use weak keyword, but I want keep the reference until UIView is deallocated.
Those two designations - unowned and weak - are equivalent from the perspective of references. Where they differ is the presumption of existence - in Swift, unowned instances are presumed to always exist as long as reference to them does, whereas weak instances are optionals - they may exist, or they may not, so you need to use optional chaining or some other means of working with them.
In UIKit, the delegate pattern with UIView subclasses is to declare them as weak because the delegate is nearly always the view controller that owns the view that the subclass is a subview of. Declaring a delegate as strongly referenced in that situation would set up a reference cycle, hence delegates are typically declared with the weak keyword. If you have a different situation, you can allow your delegate to be strongly referenced by simply leaving out the weak keyword.
In this particular case, unowned (unsafe) is an artifact of being bridged from ObjC.
how to define a unowned(unsafe) reference delegate for UIView
You can't. And you shouldn't want to. unowned(unsafe) is a way of expressing the Objective-C non-ARC assign policy, i.e. no memory management. It is horrible and dangerous (and can cause crashes). The name tells you what the problem is. It is unsafe!!! There is no Swift equivalent because Swift has built-in memory management. This is one of the reasons why Swift is good. Don't worry be happy.
But do be careful, because this designation is warning you that if the delegate goes out of existence while the UITableView still exists, you will crash because the table view will not know this and may try to send a message to the non-existent delegate.

array of delegates for callback not safe?

I understand in the delegate pattern for iOS you want the reference to the delegate to be weak, but if I for instance have this:
#property (nonatomic, weak) NSMutableArray *delegates;
and in this array are instances of
id<myDelegateCallback>
The Array has a strong retain of the items inside.
Do I alloc/init the array inside the class that has this as it's property or do I set the array to an instance owned by another class?
Or is this not a good implementation of the Delegate pattern? I understand I can use Notifications and such, but wanted to know if this would actually work without any ARC issues.
You can only have one designated delegate object, not an array of delegates. Some classes have a delegate AND a "data source" that conform to unique protocols, but that only makes sense for objects that need to get their content from some designated place.
But if you want to notify several listening objects of some thing happening, consider using a NSNotification registered with NSNotificationCenter. The downside is that there's no formal or declared protocol methods for the listeners to conform to (and for the compiler to complain about if there's any issues).
Here's a related question with more useful information.
If you really need an array of weak delegates, you can use a bridged CFMutableArray initialized with NULL retain and release callbacks.
See more here: https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFMutableArrayRef/Reference/reference.html#//apple_ref/doc/uid/20001502

objective-c: multiple class defintions in one .m file, and calling methods

I've defined two classes in an m file, the first subclassing UIView and the second UIViewController. The UIViewController is instantiated at some point, and the vc is who instantiates my first class.
the first class implements the touchesEnded method, to simulate a button. when the touchesEnded method is fired in the first class, is it possible to easily call a method defined in the 2nd class, without going into delegates and such?
I tried playing with selectors with no luck
is it possible to easily call a method defined in the 2nd class
Yes, assuming that you are creating an instance of the second class and calling the method on that instance.
Regardless of whether the two classes are subclasses of the same type, or in the same or different files, you need a reference to an instance of that class to call a method on it, or force it to perform a selector.
The proper OO way to do this is with delegates, but you could theoretically do something like pass a reference to view 2 into view 1 when you create the views. If you create them in IB you could create outlets so they reference each other that way.
In short: Yes, it is possible and easy to do, but I can't give you too much in terms of specific code without a more specific example of your situation

passing array from one view to another

i am a new iphone programmer i want to create an array that keeps adding a value at its last position when i moving from one view to another
because at last view ,i need that full array which has all values from all views....
i tried taking an array and sending it view to next view (array is defined in all views) but when i tried to put value to it
You can use NSMutableArray class with addObject: in order to add your views into array. Have a single view controller, declare that array and all your views can access the view controller's array.
try to save it to a class (singelton class) it will work....it will surely work if you transfer it to the delegate class....make an NSMutableArray object there and initialize it once in applicationDidFinishLaunching method and then make object of delegate class and transfer your values to it by addObject method.....
The best way is initialize your mutablearray in appdelegate and use the same using the object of delegate in each class wherever you want to use.you can add the object using addobject and can access using property objectAtIndex anywhere.

What's the best way to have functions share an array in Objective-C?

I understand that in Objective-C you declare an array in the header file and interact with it in a class. So far I'm adding things and fetching them fine within a single function. I'm new to the language however and can't figure out how to share that array across other functions.
I'd like to initialize array data in my viewDidLoad and access it from various functions later on. Is this possible and if so what's the best way to do it?
Like you said, declare the array in the view controller's header file and make it a #property. Use alloc-init in the implementation's -viewDidLoad method to set it up. Deallocate it in the dealloc method. Use its property setter (self.array) to retain or assign another array, depending on the #property attribute. Access it directly (array) throughout your methods in your class implementation, and via its property getter (obj.array) from other classes.