• 关于

    Delegates

    的搜索结果

问题

如何在Objective-C里创建委托(delegates)?

我知道委托如何工作,我也知道怎么使用。但是我该怎么创建呢?原文:How do I create delegates in Objective-C?I know how delegates work, and I know how I can...
a123456678 2019-12-01 20:28:01 849 浏览量 回答数 1

问题

关于每次UItextfield输入数字执行delegates

每次UITextfield 接收到一个数字时都要执行一个方法。好像是用textfieldDidBeginEditing和textfieldShouldChangeCharacterInRange,但不清楚怎么用相应的delegates。...
爵霸 2019-12-01 20:27:14 819 浏览量 回答数 1

问题

关于startMonitoring在ios5不运行 的问题

初始化location Manager:self.locationManager = [[[CLLocationManager alloc] init] autorelease]; self.locationManager.delegate...
爵霸 2019-12-01 19:23:52 680 浏览量 回答数 1

万券齐发助力企业上云,爆款产品低至2.2折起!

限量神券最高减1000,抢完即止!云服务器ECS新用户首购低至0.95折!

回答

可以创建,没问题,导入类之后你可以创建delegates。
爵霸 2019-12-02 02:24:33 0 浏览量 回答数 0

问题

在ios中获取UIKeyboard显示情况

怎么判断应用中UIKeyboard是否开启了?我不想用UITextField的delegates方法实现。...
爵霸 2019-12-01 19:24:33 881 浏览量 回答数 1

问题

在使用批量tableview时使用delegates

我的ViewController中有3个tableView,可不可以实现单独使用UITableViewDelegate方法?比如,可以分别对每个UITableView使用cellForRowAtIndexPath方法,但是不知道对每个tab...
爵霸 2019-12-01 19:24:48 763 浏览量 回答数 1

问题

关于ios-UIWebView 调用失败

有一个可以正常运行的UIWebView。delegates也运行正常,在打开URL时,事件 shouldStartLoadWithRequest 和 webViewDidFinishLoad 都会激活。 但是在打开google 搜索结果时,...
爵霸 2019-12-01 19:23:47 1004 浏览量 回答数 1

问题

关于在访问时报错:No visible @interface

在appdelegate.m中创建了一个方法:-(void)setupTabBarController { // details goes here }在ABC.m中访问setupTabBarController。已经包括...
爵霸 2019-12-01 19:24:42 925 浏览量 回答数 1

问题

C++11 中委派 (Delegates) 如何实现

在 C++ 中通过一个全局函数来绑定到对象的成员函数是很有用的,这个特性也存在于其他语言中,例如 C#的委派。在 C++ 中相当于成员函数指针,但是 并没有提供相应的特性。在这篇文章中,我想提出一个简单的 C++ 委派的实现,是用 C++ ...
a123456678 2019-12-01 20:05:39 1002 浏览量 回答数 1

回答

google使用的ajax,在一个有效的新资源加载到webView中才会调用webViewDidFinishLoad delegates方法。相当于一个页面加载在浏览器里,由于google使用的ajax,所以不能引起方法的触发。没有方法能检测是否部分页面被加载了(javascript,样式表,或者ajax响应)。你可以做的事是检测webView的javascript判断页面的高度,根据页面高度的变换可以判断哪些完成。你还可以想一些其他的方法来检测哪些搜索查询发生变化了,不过我的方法可以用于google初始页面的结果。每几秒检测一次JS就可以了。
爵霸 2019-12-02 02:18:36 0 浏览量 回答数 0

回答

/** * Each of these fields are initialized to contain an instance of the * appropriate view the first time this view is requested. The views are * stateless, so there's no reason to create more than one of each. */ transient volatile Set keySet; transient volatile Collection values; /** * {@inheritDoc} * * @implSpec * This implementation returns a set that subclasses {@link AbstractSet}. * The subclass's iterator method returns a "wrapper object" over this * map's <tt>entrySet()</tt> iterator. The <tt>size</tt> method * delegates to this map's <tt>size</tt> method and the * <tt>contains</tt> method delegates to this map's * <tt>containsKey</tt> method. * * <p>The set is created the first time this method is called, * and returned in response to all subsequent calls. No synchronization * is performed, so there is a slight chance that multiple calls to this * method will not all return the same set. */ public Set<K> keySet() { if (keySet == null) { keySet = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { i.remove(); } }; } public int size() { return AbstractMap.this.size(); } public boolean isEmpty() { return AbstractMap.this.isEmpty(); } public void clear() { AbstractMap.this.clear(); } public boolean contains(Object k) { return AbstractMap.this.containsKey(k); } }; } return keySet; }
蛮大人123 2019-12-02 02:24:01 0 浏览量 回答数 0

回答

AFNetworking图片下载操作是异步的,你不能在操作开始的时候指定它。 你构建的函数应该用delegates和block。 - (void)downloadImageWithCompletionBlock:(void (^)(UIImage *downloadedImage))completionBlock identifier:(NSString *)identifier { NSString* urlString = [NSString stringWithFormat:@"http://myserver.com/images/%@", identifier]; AFImageRequestOperation* operation = [AFImageRequestOperation imageRequestOperationWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { NSLog(@"response: %@", response); completionBlock(image); } failure:nil]; [operation start]; } 如下调用: // start updating download progress UI [serverInstance downloadImageWithCompletionBlock:^(UIImage *downloadedImage) { myImage = downloadedImage; // stop updating download progress UI } identifier:@""];
爵霸 2019-12-02 02:19:27 0 浏览量 回答数 0

回答

在我的方法中奖提供一个create_delegate函数,可通过下面两种方法来调用:create_delegate(&object, &member_function)create_delegate(&function)第一种方法创建一个对象并提供一个operator()成员函数,第二个方法生成一个函数指针,两种方法都兼容 type function<...>. 1 class A 2 { 3 int i; 4 public: 5 A(int k):i(k) {} 6 7 auto get()const ->int { return i;} 8 auto set(int v)->void { i = v;} 9 10 auto inc(int g)->int& { i+=g; return i;} 11 auto incp(int& g)->int& { g+=i; return g;} 12 13 auto f5 (int a1, int a2, int a3, int a4, int a5)const ->int 14 { 15 return i+a1+a2+a3+a4+a5; 16 } 17 18 auto set_sum4(int &k, int a1, int a2, int a3, int a4)->void 19 { 20 i+=a1+a2+a3+a4; 21 k = i; 22 } 23 24 auto f8 (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const ->int 25 { 26 return i+a1+a2+a3+a4+a5+a6+a7+a8; 27 } 28 29 static auto sqr(double x)->double { return x*x; } 30 }; 请注意你并不需要一定使用 C++ 的 auto 函数语法,你也可以使用传统的方法,然后我们使用下面方法创建一个类:`1A a(11);`接下来我们创建委派: 1 auto set1 = create_delegate(&a,&A::set); 2 auto inc = create_delegate(&a,&A::inc); 3 std::function<int(int&)> incp = create_delegate(&a,&A::incp); 4 auto af5 = create_delegate(&a,&A::f5); 5 auto set_sum4= create_delegate(&a,&A::set_sum4); 6 auto af8 = create_delegate(&a,&A::f8); 7 auto sqr = create_delegate(&A::sqr); // static function </int(int&)> 1 set1(25); 2 int x = 5; 3 int k = inc(x); 4 k = incp(x); 5 std::cout << "a.get():" << a.get() << std::endl; 6 std::cout << "k: " << k << std::endl; 7 std::cout << "x: " << x << std::endl; 8 std::cout << "af5(1,2,3,4,5): " << af5(1,2,3,4,5) << std::endl; 9 10 set_sum4(x,1,2,3,20); 11 std::cout << "after set_sum4(x,1,2,3,20)" << std::endl; 12 std::cout << "a.get(): " << a.get() << std::endl; 13 std::cout << "x: " << x << std::endl; 14 std::cout << "af8(1,2,3,4,5,6,7,8): " << af8(1,2,3,4,5,6,7,8) << std::endl; 15 std::cout << "sqr(2.1): " << sqr(2.1) << std::endl; 执行上述程序的打印结果如下: 1 a.get():30 2 k: 35 3 x: 35 4 af5(1,2,3,4,5): 45 5 after set_sum4(x,1,2,3,20) 6 a.get(): 56 7 x: 56 8 af8(1,2,3,4,5,6,7,8): 92 9 sqr(2.1): 4.41 关键点 对于一个不是 volatile 和 const 的简单函数而言,实现是非常简单的,我们只需要创建一个类保存两个指针,一个是对象,另外一个是成员函数: 1 template <class T, class R, class ... P> 2 struct _mem_delegate 3 { 4 T* m_t; 5 R (T::*m_f)(P ...); 6 _mem_delegate(T* t, R (T::*f)(P ...) ):m_t(t),m_f(f) {} 7 R operator()(P ... p) 8 { 9 return (m_t->*m_f)(p ...); 10 } 11 }; 可变模板 variadic template 允许定义任意个数和类型参数的operator()函数,而create_function 实现只需简单返回该类的对象: 1 template <class T, class R, class ... P> 2 _mem_delegate<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...)) 3 { 4 _mem_delegate<T,R,P ...> d(t,f); 5 return d; 6 } 实际中,我们需要另外的三个实现用于覆盖 const、volatile 和 const volatile 三种成员函数,这也是为什么传统使用 #define 宏很便捷的原因,让你无需重写代码段,下面是完整的实现: 1 template <class F> 2 F* create_delegate(F* f) 3 { 4 return f; 5 } 6 #define _MEM_DELEGATES(_Q,_NAME)\ 7 template <class T, class R, class ... P>\ 8 struct _mem_delegate ## _NAME\ 9 {\ 10 T* m_t;\ 11 R (T::*m_f)(P ...) _Q;\ 12 _mem_delegate ## _NAME(T* t, R (T::*f)(P ...) _Q):m_t(t),m_f(f) {}\ 13 R operator()(P ... p) _Q\ 14 {\ 15 return (m_t->*m_f)(p ...);\ 16 }\ 17 };\ 18 \ 19 template <class T, class R, class ... P>\ 20 _mem_delegate ## _NAME<T,R,P ...> create_delegate(T* t, R (T::*f)(P ...) _Q)\ 21 {\ 22 _mem_delegate ##_NAME<T,R,P ...> d(t,f);\ 23 return d;\ 24 } 25 26 _MEM_DELEGATES(,Z) 27 _MEM_DELEGATES(const,X) 28 _MEM_DELEGATES(volatile,Y) 29 _MEM_DELEGATES(const volatile,W)
a123456678 2019-12-02 01:56:37 0 浏览量 回答数 0

问题

underscore.js的bind函数

先贴代码:var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { if (!(callingContext instanceof...
小旋风柴进 2019-12-01 20:23:43 925 浏览量 回答数 1

回答

优点kotlin提供了很多好的特性,比如:null安全检测,属性访问,unchecked exceptions, publication有更详细的介绍。 1.1 java 自动转换成kotlinkotlin项目开发总结有介绍如何使用,这个是有JetBrains提供的,目前已经集成到了IDEA/AS, 虽然它不是很完美(我的上篇博客也已经介绍到了),但是对比重新用Kotlin开发一个完全一样功能的类来说,可以节省不少时间。 1.2 lateinit Delegates.notNull and lazykotlin的null安全监测是个非常好的特性,但是也有有个问题,比如: var aMap: AMap? = null onCreate(){ aMap = ... aMap!!.projection .... }1234567虽然我们可以保证aMap已经在onCreate方法定义了,但是因为我们在定义aMap的时候是AMap?类型,所以在以后使用的都必须使用aMap!!来告诉编译器aMap不为null,会显得非常麻烦。幸运的是kotlin已经帮我们考虑到了应对方法 lateinit var name: Stringvar age: Int by Delegates.notNull()12通过上面两种方法,可以在定义的时候不提供初始化,可以延迟到需要的时候,但是就像我在kotlin项目开发总结说的,需要慎用,除非你能确保不会在后面遗漏掉重新赋值,否则会在运行时报空指针错误,这就浪费了kotlin的null安全监测这个非常好的特性。 lazy代理是个很好用的东西,就像下面这样的定义 val imm: InputMethodManager by lazy { getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager }123lazy后面跟着的block只会在你第一次read这个imm的时候调用,以后读取imm会直接返回block保存的值。在需要追求启动速度的APP可以很好的使用。 1.3 扩展后的collectionskotlin提供了很多对collections和iterables的扩展,具体可以看下 我写的分析和使用collections。 1.4 Named 和 默认的函数参数Named 函数参数和默认函数参数非常简单,但有时候可以帮我们省掉很多代码。特别是当构造函数有超过4个以上的参数时,可以指定默认几个默认参数,在调用的时候可以只提供一个参数。比如 class Presenter( val okhttp: OkHttp = productionOkHttp(), val picasso: Picasso = productionPicassoInstance() ) {...}1234在调用的时候,我们不提供参数,那么默认参数会被使用 var prensenter = Presenter()1 缺点虽然kotlin非常强大,但它毕竟不是完美的。它也会有一些可能未来会解决的缺点。 2.1 编译速度慢大家在使用kotlin开发项目的时候应该有注意到了,主要还是因为kotlin会自动自动生成更多的代码,比如为属性生成get/set, 对比java会存在更多的方法数量。https://youtrack.jetbrains.com/issue/KT-6246,这篇博客有做分析 2.2 annotation processing的问题我目前开发的项目使用了dagger,permissionsdispatcher,deeplinkdispatch,databinding,都需要使用kapt来做annotation proccessing,但是我已经碰到了好多次,kapt报的很奇怪的错误,有一次,我重构dagger的module时,报了一个蛋疼的问题,我以为我是dagger没用好,找了很多资料对比都没有解决,花了大概一天的时间,后面没办法只能clean project,但是奇怪的问题还在,后面我让application继承了DaggerApplication,clean下就可以。后面还是碰到好几次这样的问题,都是clean之后build就可以了,这个问题应该不只我一个人碰到,我想可能是kapt的一个bug, 我还是很相信google/JetBrains, 所以还是继续坚持使用kotlin开发项目。 2.3 没有命名空间kotlin允许定义top-level的函数和属性,比如 //demo.ktvar a = "aa"fun printlnA(){ println(a) }12345这可能是一个非常好的特性,但是也会有问题,比如在项目下面有两个甚至更多的printlnA方法,那么在调用的时候(特别是在阅读代码),很难区分方法来自哪个地方,除非你F3跳转到声明处。为了避免这个问题,你可以选择把printlnA方法移到一个object中,比如 object PrintlnHelper{ fun printlnA(){ println(a) } }12345让我们来看下kotlin和java的调用方式 //kotlinPrintlnHelper.printlnA()//javaPrintlnHelper.INSTANCE.printlnA()1234为了避免如上在Java中调用的怪怪的。。,可以使用@JvmStatic注解该方法 object PrintlnHelper{ @JvmStatic fun printlnA(){ println(a) } }123456通过上面的分析,对于有代码洁癖或者同时用Java和kotlin开发的项目,也是不够完美的,这个缺点是可以避免的,但是你需要花费一点时间去熟悉Kotlin 2.4 没有静态修饰语还是像上面的问题,如果项目同时存在kotlin和Java,而且Java需要调用kotlin代码,看代码分析问题 //Javapublic class View { public static final int VISIBLE = 0x00000000; public static final int INVISIBLE = 0x00000004; public static View inflate(Context context, int resource) {...} }123456使用kotlin使用同样的功能,如下: class View { companion object { @JvmField val VISIBLE: Int = 0x00000000 @JvmField val INVISIBLE: Int = 0x00000004 @JvmStatic fun inflate(context: Context, resource: Int) {...} } }12345678910下面是有@JvmField和没有的Java调用方式 // With annotations:View.VISIBLE;//Without annotations:View.Companion.getVISIBLE();1234其实这个问题也不是很严重的,但是对比Java还是多了个@JvmField, 但是kotlin新手或者容易忘记,使用@JvmField,这个缺点可以通过熟悉kotlin来避免 2.5 Java自动转换成kotlin带来的问题Java自动转换成kotlin是个非常好的特性,但是也会带来问题。Javadoc原来的结构会被破坏掉,静态field和方法会转换成companion object中的普通声明,如果有Java代码调用这个类,就会出现点问题,除非你后面手动给这个转换后的companion object 添加上@JvmField和@JvmStatic。这是个不小的隐患,需要特别注意下。 2.6 会增加方法数量过多的方法数量会导致编译速度变慢。kotlin通过闭包,内联函数等可以显著减少代码的总行数,但它可能也会增加编译后的方法数量。对于Android项目来说这肯定是一个不小的缺点。有很多原因会导致方法数量增加,但是最大的来源是kotlin实现属性。 kotlin不像Java可以直接访问field, 而是通过创建property的方式来访问。这是一个很好的特性,你可以自定义实现property的set/get,对比Java的set/get方法是个很大的进步。 但是这个是有代价的,对于val属性,kotlin自动生成backing field和getter函数来供java调用。public var属性会自动生成setter/getter函数。幸运的是private var属性已经有默认的setter/getter,需要不需要额外生成。所以这个时候你想想如果你定义了很多个public var和val属性,那么kotlin会帮你自动生成更多的函数,所以带来的后果就是方法数量会越来越多,导致编译速度变慢。 假如方法数量已经接近限制,不需要使用自定义setter的属性可以用@JvmField修饰,被@JvmField修饰的属性不会自动生成setter/getter函数,如下 @JvmFieldvar aMap: aMap? = null122.7 “==”在kotlin中,”==”和”equals”都是比较引用是否相等。如何项目中只有kotlin代码,那这个肯定是个非常好的特性,但是如果项目同时包含java和kotlin(比如:你是在旧的java工程基础上,用kotlin开发新功能),那么“==”很容易产生混淆和错乱。 设计原则3.1 kotlin的class默认是final, 如果想要能被继承,那么需要使用open 修饰,它的设计原则来自于 Effective Java 这种默认的设计原则,会导致第三方/未完成的sdk的大多数会是不可继承的,从提供者角度来说:它必须保证这个类是足够完整的,从使用者角度来说:这个类必须要提供我需要的所有东西,否则,我必须重写。当然提供者可以为这个类加上open来表示这个类是可以继承的,但是这是另外一种设计思维。 Roedy Green, How to Write Unmaintainable Code有提到: 给你的所有类设置为final。 毕竟,你完成了这个项目 - 当然没有人可以通过扩展你的class来改善你的工作。 这甚至可能是一个安全漏洞 - 毕竟,为什么不是java.lang.String final? 如果您的项目中的其他编程人员抱怨,请告诉他们您的执行速度提升 3.2 错误的使用运算符重载kotlin允许对类的变量运算符进行重载,设想有下面的代码 var person3 = person1 + person21 “+” 这个运算符有可能在很多个地方做了重载,在后期维护代码,很难区分哪个是哪个 作者:安卓机器人 来源:CSDN 原文:https://blog.csdn.net/ncuboy045wsq/article/details/74853107 版权声明:本文为博主原创文章,转载请附上博文链接!
auto_answer 2019-12-02 01:49:53 0 浏览量 回答数 0

回答

简单来说,代理是一种编程模式,它将某个操作转移给另外一个对象来实现。 最简单的形式可能是像下面这样: class A: def spam(self, x): pass def foo(self): pass class B1: """简单的代理""" def __init__(self): self._a = A() def spam(self, x): # Delegate to the internal self._a instance return self._a.spam(x) def foo(self): # Delegate to the internal self._a instance return self._a.foo() def bar(self): pass 如果仅仅就两个方法需要代理,那么像这样写就足够了。但是,如果有大量的方法需要代理, 那么使用 __getattr__() 方法或许或更好些: class B2: """使用__getattr__的代理,代理方法比较多时候""" def __init__(self): self._a = A() def bar(self): pass # Expose all of the methods defined on class A def __getattr__(self, name): """这个方法在访问的attribute不存在的时候被调用 the __getattr__() method is actually a fallback method that only gets called when an attribute is not found""" return getattr(self._a, name) __getattr__ 方法是在访问attribute不存在的时候被调用,使用演示: b = B() b.bar() # Calls B.bar() (exists on B) b.spam(42) # Calls B.__getattr__('spam') and delegates to A.spam 另外一个代理例子是实现代理模式,例如: # A proxy class that wraps around another object, but # exposes its public attributes class Proxy: def __init__(self, obj): self._obj = obj # Delegate attribute lookup to internal obj def __getattr__(self, name): print('getattr:', name) return getattr(self._obj, name) # Delegate attribute assignment def __setattr__(self, name, value): if name.startswith('_'): super().__setattr__(name, value) else: print('setattr:', name, value) setattr(self._obj, name, value) # Delegate attribute deletion def __delattr__(self, name): if name.startswith('_'): super().__delattr__(name) else: print('delattr:', name) delattr(self._obj, name) 使用这个代理类时,你只需要用它来包装下其他类即可: class Spam: def __init__(self, x): self.x = x def bar(self, y): print('Spam.bar:', self.x, y) # Create an instance s = Spam(2) # Create a proxy around it p = Proxy(s) # Access the proxy print(p.x) # Outputs 2 p.bar(3) # Outputs "Spam.bar: 2 3" p.x = 37 # Changes s.x to 37 通过自定义属性访问方法,你可以用不同方式自定义代理类行为(比如加入日志功能、只读访问等)。
哦哦喔 2020-04-17 15:06:36 0 浏览量 回答数 0

问题

Write operations are not allowed in read-only mode (FlushMode.MANUAL)

Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or r...
a123456678 2019-12-01 20:25:45 1308 浏览量 回答数 1

回答

来自@Jesse Rusak 的回答: Objective-C 委托就是已被指定为另一个委托的对象,没有特殊的创建过程,你只要定义一个实现你感兴趣的委托方法的类就可以。(虽然委托使用正式协议,但你必须得声明委托来执行该协议,如下所示)例如,假设你有个NSWindow。如果你想要实现他的委托的 windowDidMove: 方法,你可以创建一个这样的类: @implementation MyClass (void)windowDidMove:(NSNotification*)notification { // ... } @end然后创建一个MyClass的实例并制定为window的委托: MyClass *myDelegate = [[MyClass alloc] init];[window setDelegate: myDelegate];在NSWindow方面, 可能有类似于此的代码使用 respondsToSelector: 来看委托是否响应windowDidMove:信息,如何合适就发送。 if([[self delegate] respondsToSelector:@selector(windowDidMove:)]) { [[self delegate] windowDidMove:notification]; }委托资源本身是典型声明的weak(ARC)或assign(预ARC)来避免循环,因为对象委托经常持有强引用该对象(例如,一个视图控制器通常包含视图委托)要定义自己的委托,你需要在某个地方声明方法。有两个基本的方法,苹果的文档协议有讨论过. 1) 一个非正式的协议 这个就和NSWindow差不多,在NSObject的类别实现。例如,继续上面的例子,这是从NSWindow.h:转述的: @interface NSObject(NSWindowNotifications) (void)windowDidMove:(NSNotification *)notification;// ... 其他方法 @end就像上面描述的那样,当调用这个函数的时候,你会使用-respondsToSelector:,委托简单的实现此方法,就完成了。这个方法在苹果的库里是直接常见的,但是新的代码应该是用下面的更现代的方法。 2)一个正式的协议 新的选择是声明一个正式的协议。声明应该像这个样子: @protocol NSWindowNotifications @optional (void)windowDidMove:(NSNotification *)notification;// ...其他方法 @end这类似于一个借口或者抽象基类,因为这为委托建立了一个特殊的类型,这种情况下是NSWindowNotifications。委托执行者应该采用这个协议: @interface MyDelegate // ...@end然后再协议中执行方法。对于诸如@optional(就和大多数委托方法一样)在协议中声明的方法,你仍然需要在调用特殊方法之前检查-respondsToSelector:。苹果建议这种方法,因为这个更精确,不会和NSObject弄混,并且提供更好的工具支持。 优化速度 代替检查委托是否响应选择器,你可以在设置委托时存储相关信息。使用bitfield是一个非常清晰的方法,如下: @protocol SomethingDelegate @optional (void)something:(id)something didFinishLoadingItem:(id)item; (void)something:(id)something didFailWithError:(NSError *)error;@end @interface Something : NSObject@property (nonatomic, weak) id delegate;@end @implementation Something { struct { unsigned int didFinishLoadingItem:1; unsigned int didFailWithError:1; } delegateRespondsTo;}@synthesize delegate; (void)setDelegate:(id )aDelegate {if (delegate != aDelegate) { delegate = aDelegate;delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)]; delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];} }@end然后,在正文里,可以通过访问delegateRespondsTo来检查委托处理邮件,而不是一遍又一遍的发送-respondsToSelector:。 来自@Tibidabo 上面的方法很厉害!但是如果你想在1分钟之内解决问题可以尝试一下这个:MyClass.h文件应该像这个样子(用评论添加委托行) import @class MyClass; //定义类,这样协议可以看到MyClass@protocol MyClassDelegate //定义委托协议 (void) myClassDelegateMethod: (MyClass *) sender; //定义在另一个类里实现的委托方法@end //结束协议 @interface MyClass : NSObject {}@property (nonatomic, weak) id delegate; //定义 MyClassDelegate为委托 @endMyClass.m 文件应该像这样: import "MyClass.h" @implementation MyClass @synthesize delegate; //综合MyClassDelegate 委托 (void) myMethodToDoStuff {[self.delegate myClassDelegateMethod:self]; //这个会调用在其他类里实现的方法 } @end为了在其他的类里使用委托(本情况是UIViewController调用MyVC)MyVC.h: import "MyClass.h" @interface MyVC:UIViewController { //make it a delegate for MyClassDelegate}MyVC.m: myClass.delegate = self; //设置委托至自身的某个地方执行委托方法: (void) myClassDelegateMethod: (MyClass *) sender { NSLog(@"Delegates are great!"); } 来自@umop 当用正式的协议方法创建委托支持时,我发现可以确保正确的类型检查(虽然是运行时间,不是编译时间),通过添加如下代码: if (![delegate conformsToProtocol:@protocol(MyDelegate)]) { [NSException raise:@"MyDelegate Exception" format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__]; }在你的委托访问(setDelegate)代码,这个能将错误最小化。 来自@Tom Andersen的回答 或许更多的是在于你所缺少的行。如果从C++的视角来看,委托需要一点时间适应,但是基本上“他们只是工作”。委托实现的方式是:设置NSWindow的委托对象,但是对象只为一个或几个可能的委托方法执行。所以会发生一些事,NSWindow想要调用对象,它只使用Objective-c的respondsToSelector方法来决定对象是否被调用,然后再调用。这就是objective-c的实现方式——根据需求寻找方法。用你自己的对象实现这一点是非常琐碎的,没有什么特别的事情,你甚至可以为让一个实例有27个对象的NSArray,完全不同类型的对象,其中只有18个有-(void)setToBue;方法,其他的9个没有。所以在18个需要完成的调用setToBlue,就像这样: for (id anObject in myArray){ if ([anObject respondsToSelector:@selector(@"setToBlue")]) [anObject setToBlue]; }另外,委托是不保留的,所以需要在MyClass dealloc方法中将委托设置为nil。 来自@RDC 的回答: 请看下面的教程是如何一步一步介绍iOS中的委托的。 iOS中的委托我创建了两个 ViewControllers (从一个给另一个发送) FirstViewController 执行委托(提供数据). SecondViewController声明委托(接收数据).
a123456678 2019-12-02 03:13:13 0 浏览量 回答数 0

云产品推荐

上海奇点人才服务相关的云产品 小程序定制 上海微企信息技术相关的云产品 国内短信套餐包 ECS云服务器安全配置相关的云产品 开发者问答 阿里云建站 自然场景识别相关的云产品 万网 小程序开发制作 视频内容分析 视频集锦 代理记账服务 阿里云AIoT