3

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

2
  • I hope you are familiar with cryptographic pseudo random number generators (PRNG). Also /dev/random and arc4random. Commented Dec 24, 2013 at 21:59
  • I wouldn't be doing this otherwise. This is mainly for my own research and learning. Commented Dec 24, 2013 at 22:05

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I'll confirm if this works after work today and if it does go ahead and accept the answer. Thanks! Makes perfect sense!
Martin, the method you gave doesn't work with ARC enabled, but changing id to NSObject does work, or removing the pointer from bar. I remember reading somewhere that id and NSObject aren't really the same thing (I'm gonna go back and re-read that section of my book to be sure) so that might explain it. Anywho, after changing it to NSObject, OR removing the pointer notation, it works just fine. Thanks!
@Zarazthuztra: you are right, id is already a pointer, that was my fault and I will fix it in the answer. Anyway, I'm glad that it helped.
No worries dude, I wouldn't have picked up on that if xcode hadn't yelled at me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.