【问题标题】:Using Obj-C protocols like Java Interfaces for pluggability of classes使用诸如 Java 接口之类的 Obj-C 协议来实现类的可插入性
【发布时间】:2013-12-24 20:05:46
【问题描述】:

背景:作为个人实验,我对研究和尝试创建更好的随机数生成器很感兴趣。此外,我开始学习和学习 Objective-C 和 iOS 开发。因此,我认为一个很好的实践项目是将我的随机数生成器想法移植到 iOS 应用程序中以获得乐趣。我在 Java 方面有很强的背景,所以我已经多次完成了我将要提到的事情,但是我的 Objective-C 技能还很幼稚,所以我不确定如何去做。

意图:我正在使用 UITableVIew 来提供我想出的生成器列表。同样,这是为了试验我的想法,练习我的 iOS 开发技能,但我正在尝试做一些事情,让我未来的开发变得更干净、更容易。我一直在尝试使用 Obj-C 协议来实现我想要做的事情,根据我的研究和阅读,它们实际上与 Java 中的接口相同。

所以,我想做的是能够定义一个协议(我已经知道该怎么做),要求任何“实现”该协议的人实现其中的方法(我已经知道该怎么做)但是能够声明由协议定义的类型的对象,而不是通过特定的随机数类,这样创建新生成器并将其添加到列表中很容易,因为我不必担心将任何东西链接到表,只需添加符合协议的新生成器类即可。我知道我想要什么,我知道这些词,我只是不知道如何表达它。

我做了什么:

在 Java 中,以下是可能的、有效的和常见的:

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();
    }
}

这会很好地将 Hello 打印到控制台。我见过很多人这样做的例子,我自己也用 Java 做过好几次。

这是我在 Objective-C 中尝试做的事情:

Bar.h 假设有必要 #import

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

MyConformingViewController.m 假设接口已声明,并且导入已处理

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

MyTableViewController.m 假设接口已经声明

@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

问题结束

所以我在这里想要弄清楚的是如何模拟我在 Java 中所做的事情。其中大部分我可以自己弄清楚,但我很难说出我遇到的这个特定问题。如果您需要更多信息或有任何其他架构建议,请告诉我。我查看了this question on protocols,但它并没有以我希望的方式回答问题,而且我还阅读了我的书和苹果关于协议的所有文档。据我所知,我只是想得太难了,而且很简单。

流程:

声明协议

在视图控制器中实现协议

在 Table View Controller 中,能够创建实现该协议的对象实例

根据用户点击的内容加载选定的视图控制器

在 Table View Controller 中仅显示那些实现该协议的类

【问题讨论】:

  • 我希望您熟悉加密伪随机数生成器 (PRNG)。还有 /dev/random 和 arc4random。
  • 否则我不会这样做。这主要是为了我自己的研究和学习。

标签: java ios objective-c interface protocols


【解决方案1】:

我认为你说得差不多了,但是

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

应该是

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

因为id &lt;Bar&gt; 声明了一个符合Bar 协议的Objective-C 对象。

【讨论】:

  • 我会在今天下班后确认这是否有效,是否继续并接受答案。谢谢!很有道理!
  • Martin,您提供的方法在启用 ARC 的情况下不起作用,但将 id 更改为 NSObject 确实有效,或者从 bar 中删除指针。我记得在某处读到 id 和 NSObject 并不是一回事(我要回去重新阅读我的书的那部分以确定),这样可以解释它。 Anywho,在将其更改为 NSObject 或删除指针符号后,它工作得很好。谢谢!
  • @Zarazthuztra:你是对的,id 已经是一个指针,这是我的错,我会在答案中解决它。无论如何,我很高兴它有所帮助。
  • 别担心,伙计,如果 xcode 没有对我大喊大叫,我就不会明白这一点 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 2015-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
相关资源
最近更新 更多