Domanda

Background: I've had an interest in studying and trying to create better random number generators as a personal experiment. Additionally, I've taken up studying and learning Objective-C and iOS development. So, I figure a great practice project would be to port my random number generator ideas to an iOS application for fun. I have a rather strong background in Java, so I've done things like what I'm about to mention before several times, but my Objective-C skills are quite nubile so I'm unsure about how to go about this.

Intent: I am using a UITableVIew to provide a list of generators I've come up with. Again, this is to experiment with my ideas, and practice my iOS development skills, but I'm trying to do something that will make my future development a little cleaner and easier. I've been trying to use an Obj-C protocol to achieve what I'm trying to do, as according to my research and reading they are effectively the same as an interface in Java.

So, what I'd like to do is be able to define a protocol (which I already know how to do) requiring anyone who "implements" that protocol to implement the methods inside (which I already know how to do) BUT be able to declare objects of the type defined by the protocol, and not by a specific random number class, this way creating and adding new generators to the list is easy, as I don't have to worry about linking anything up to the table, just add the new generator class that conforms to the protocol and go. I know what I want, I know the words, I'm just not sure how to phrase it.

What I've done:

In Java, the following is possible, valid, and common:

Bar.java

public interface Bar{

    public void sayHello();

}

Foo.java

public class Foo implements Bar{

    public void sayHello(){
        System.out.println("Hello");
}

Main.java

import com.somepackage.*;//so we can go ahead and pickup everything I've put in there

public class Main{
    public static void main(String[] args){
        Bar bar = new Foo();//usually figure out how I'm going to autoload the class instead of instantiating it manually so as not to break my architecture and pluggability.
        bar.sayHello();
    }
}

And that will print Hello nicely to the console. I've seen lots of examples of folks doing this, and I've done it several times myself in Java.

Here is what I've tried to do in Objective-C:

Bar.h assuming necessary #import

@protocol Bar : NSObject
    -(NSInteger) generateRandomNumber;
@end

MyConformingViewController.m assuming interface is declared already, and imports handled

@interface MyConformingViewController() <Bar>
@end
@implmentation MyConformingViewController
    -(NSInteger) generateRandomNumber{
        return 0;
    }
@end

MyTableViewController.m assuming interface is declared already

@interface MyTableViewController
@end

@implementation MyTableViewController

//assume normal methods for a view controller are in place

//only load views into the table view that conform to that protocol

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    Bar *bar = [[MyConformingViewController alloc] init];//build will fail
    //insert proper logic to load the view tapped on based on whether or not it conforms to that protocol
}

@end

End of question

So what I'm trying to figure out here is how to simulate what I've done in Java. Most of this I can figure out myself, but I'm having a hard time phrasing this particular issue I'm hitting. Please let me know if you need more information, or have any other architecture suggestions. I've looked at this question on protocols but it didn't answer the question in the way I've hoped, and I've also read all the documentation from my book and from apple on protocols. For all I know I'm just thinking too hard and it's pretty simple.

Flow:

Declare Protocol

Implement protocol in a View Controller

In Table View Controller, be able to create instances of objects which implement that protocol

Load the selected View Controller based on what the user taps on

Display in the Table View Controller only those classes which implement that protocol

È stato utile?

Soluzione

I think you got it almost right, but

Bar *bar = [[MyConformingViewController alloc] init];

should be

id <Bar> bar = [[MyConformingViewController alloc] init];

because id <Bar> declares an Objective-C object that conforms to the Bar protocol.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top