0

当 iOS 3.0 发布时,我做了一些iOS开发工作,但两年来我都忘记了 iOS 是如何做的。

我记得您确实会在iOS3.0 中保留,即使如此,我仍然不记得在二传手中保留的确切原因是什么。到目前为止,这只是让我难过的一件事。

最后但并非最不重要的一点是,在带有 ARC 的 iOS 5 中,默认情况下局部变量很强大。如果他们中的一些人没有二传手,他们怎么能强大呢?(例如,id。)

一些代码来解释我的意思:

+(double) popOperandOffStack:(NSMutableArray *) stack{
    double result = 0;

    id topOfStack = [stack lastObject];

// how is topOfStack retaining [stack lastObject] if it's simply id?

    if (topOfStack) [stack removeLastObject];

    if ([topOfStack isKindOfClass:[NSNumber class]]){
        result = [topOfStack doubleValue];
    }
    else if ([topOfStack isKindOfClass:[NSString class]]){

        if ([topOfStack isEqualToString:@"+"]){
            result = [self popOperandOffStack:stack] + [self popOperandOffStack:stack];
        }

        if ([topOfStack isEqualToString:@"-"]){
            result = [self popOperandOffStack:stack] - [self popOperandOffStack:stack];
        }

        if ([topOfStack isEqualToString:@"*"]){
            result = [self popOperandOffStack:stack] * [self popOperandOffStack:stack];
        }

        if ([topOfStack isEqualToString:@"/"]){
            result = [self popOperandOffStack:stack] / [self popOperandOffStack:stack];
        }


    }

    return result;
}
4

2 回答 2

2

您可以在编译时不知道它们的确切类型的情况下向对象发送消息。事实上,当您向从数组返回的对象发送消息时,您通常会这样做:您不需要转换id为确切的类型,您可以简单地发送一条消息,Objective C 将正确地发送它。此规则的唯一例外是使用点.语法访问属性:您确实需要在那里进行强制转换。

其类继承自的每个对象都会NSObject响应retainreleaseautorelease等等。这就是 ARC 需要知道的全部内容。id在最坏的情况下,如果您碰巧指向无效的内容,您将收到“对象不响应选择器”消息。

于 2012-07-21T04:32:17.803 回答
1

You appear to be confusing properties with instance variables and local variables.

Variables do not have setters. Properties have setters. Properties of any type can have setters (except possibly void). Instance variables might happen to correspond to properties, but the variables themselves do not have "setters". obj->ivar will never call a setter, not even under ARC.

ARC simply does approximately three things:

  1. Insert retain, release, autorelease, and dealloc for you. When you write

    // ARC
    {
      id foo = [array lastObject];
      ...
    }
    

    it gets translated to approximately

    // MRC
    {
      id foo = [[array lastObject] retain];
      ...
      [foo release];
    }
    

    It uses Objective-C naming conventions to figure out what it needs to retain and release. There are a few optimizations (it actually uses objc_retain() and friends for reasons described in the ARC spec, plus a few more functions to handle autoreleased objects more efficiently than -autorelease.)

  2. Release __strong ivars in -dealloc for you. It does not call the property setters; it just releases the ivars. It might also set them to nil.

  3. Zeroing weak references.__weak variables are read/written with objc_copyWeak() and friends instead of being accessed directly. There's additionally a hook in -[NSObject release] (or so) in order to implement zeroing weak references correctly.

Additionally, the semantics surrounding blocks and __block variables are changed in a way that isn't easy to replicate via MRC. Apart from that, I believe everything ARC does can be replicated by calling the ARC runtime support function calls.

The only connection between ARC and setters is that you can get rid of a lot of properties, because the compiler inserts retain/release on ivar access.

于 2012-07-21T05:24:58.360 回答