Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.7
    • Fix Version/s: 0.9
    • Labels:
      None
    • Environment:

      Mac OS X Lion, iOS 4.2, 4.3, 5.0..

      Description

      Objective-C in Xcode 4.2 supports ARC (Automatic Reference Counting, not GC but similar) and now it is the default both on OS X Lion and iOS 5. (ARC works on iOS 4.2 or higher.)

      The conventional Objective-C code includes many retain/release/autorelease for maintaining the life time of objects.

      Since the latest Objective-C compiler automatically generates stubs for reference counting, code should not include any retain/release/autorelease.

      Many Mac OS/iOS projects are moving to ARC mode. Although we can specify a compiler flag which tells ARC or no-ARC file by file in Xcode 4.2, there is no means to tell the Xcode that files generated by the thrift compiler are no-ARC. Xcode produces many error messages like "retain is not allowed in ARC mode".
      So, the thrift compiler should support ARC mode.

      What we need are:

      1) add -objc-arc flag to the thrift compiler.
      2) If -objc-arc flag exists, omit generating code for retain/release/autorelease.

      Please look at "Programming with ARC reference notes" in iOS developer library.

      http://andpdas.com/wp-content/uploads/2011/06/ARCProgrammingGuide.pdf

        Issue Links

          Activity

          Hide
          Jake Farrell added a comment -

          Can you please create a new ticket under the website component and attach the how to in markdown format for this.

          Show
          Jake Farrell added a comment - Can you please create a new ticket under the website component and attach the how to in markdown format for this.
          Hide
          HIRANO Satoshi added a comment -

          Thanks, Jake. I will write a wiki page after holidays.

          Show
          HIRANO Satoshi added a comment - Thanks, Jake. I will write a wiki page after holidays.
          Hide
          Hudson added a comment -

          Integrated in Thrift #347 (See https://builds.apache.org/job/Thrift/347/)
          Thrift-1340: Add support of ARC to Objective-C
          Client: Objective-c
          Patch: Hirano Satoshi

          Adds -objc-arc flag to compiler and if used removes the retain/release/autorelease from generated code

          Show
          Hudson added a comment - Integrated in Thrift #347 (See https://builds.apache.org/job/Thrift/347/ ) Thrift-1340: Add support of ARC to Objective-C Client: Objective-c Patch: Hirano Satoshi Adds -objc-arc flag to compiler and if used removes the retain/release/autorelease from generated code
          Hide
          Jake Farrell added a comment -

          Great work on this patch, can you please update the wiki page or create a new page for this so documentation is not lost.

          Committed

          Show
          Jake Farrell added a comment - Great work on this patch, can you please update the wiki page or create a new page for this so documentation is not lost. Committed
          Hide
          HIRANO Satoshi added a comment -

          Mike,

          Thanks for testing and your warm comment. My small magic for the issue of ARC/nonARC compatibility is applicable to any Cocoa project. I'm happy that you found the value of it.

          I pin it here so that many people can find. Everyone, use it in your project.

          TObjective-C.h is for supporting coexistence of both the ARC (Automatic
          Reference Counting) mode and the Non-ARC mode of Objective-C
          in the same source code.

          hirano

          /* TObjective-C.h
          *
          *

          • Licensed to the Apache Software Foundation (ASF) under one
          • or more contributor license agreements. See the NOTICE file
          • distributed with this work for additional information
          • regarding copyright ownership. The ASF licenses this file
          • to you under the Apache License, Version 2.0 (the
          • "License"); you may not use this file except in compliance
          • with the License. You may obtain a copy of the License at
            *
          • http://www.apache.org/licenses/LICENSE-2.0
            *
          • Unless required by applicable law or agreed to in writing,
          • software distributed under the License is distributed on an
          • "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
          • KIND, either express or implied. See the License for the
          • specific language governing permissions and limitations
          • under the License.
            */

          /*

          • TObjective-C.h is for supporting coexistence of both the ARC (Automatic
          • Reference Counting) mode and the Non-ARC mode of Objective-C
          • in the same source code.
            *
          • 2011/11/14 HIRANO Satoshi (AIST, Japan)
            *
          • Before:
            *
          • var = [aObject retain];
          • [aObject release];
          • [aObject autorelease];
          • [super dealloc];
          • CFFunction(obj);
            *
          • ARC and Non-ARC compatible:
            *
          • #import "TObjective-C.h"
          • var = [aObject retain_stub];
          • [aObject release_stub];
          • [aObject autorelease_stub];
          • [super dealloc_stub];
          • CFFunction(bridge_stub obj);
            *
          • Don't use retain_stub for @property(retain).
          • Use NSAutoreleasePool like this:
          • #if __has_feature(objc_arc)
          • @autoreleasepool { * // code * }
          • #else
          • NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init...
          • // code
          • [pool release];
          • #endif
            */

          #if !defined(retain_stub)
          #if __has_feature(objc_arc)
          #define retain_stub self
          #define autorelease_stub self
          #define release_stub self
          #define dealloc_stub self
          #define bridge_stub __bridge
          #else
          #define retain_stub retain
          #define autorelease_stub autorelease
          #define release_stub release
          #define dealloc_stub dealloc
          #define bridge_stub
          #endif
          #endif

          Show
          HIRANO Satoshi added a comment - Mike, Thanks for testing and your warm comment. My small magic for the issue of ARC/nonARC compatibility is applicable to any Cocoa project. I'm happy that you found the value of it. I pin it here so that many people can find. Everyone, use it in your project. TObjective-C.h is for supporting coexistence of both the ARC (Automatic Reference Counting) mode and the Non-ARC mode of Objective-C in the same source code. hirano /* TObjective-C.h * * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* TObjective-C.h is for supporting coexistence of both the ARC (Automatic Reference Counting) mode and the Non-ARC mode of Objective-C in the same source code. * 2011/11/14 HIRANO Satoshi (AIST, Japan) * Before: * var = [aObject retain] ; [aObject release] ; [aObject autorelease] ; [super dealloc] ; CFFunction(obj); * ARC and Non-ARC compatible: * #import "TObjective-C.h" var = [aObject retain_stub] ; [aObject release_stub] ; [aObject autorelease_stub] ; [super dealloc_stub] ; CFFunction(bridge_stub obj); * Don't use retain_stub for @property(retain). Use NSAutoreleasePool like this: #if __has_feature(objc_arc) @autoreleasepool { * // code * } #else NSAutoReleasePool *pool = [ [NSAutoReleasePool alloc] init... // code [pool release] ; #endif */ #if !defined(retain_stub) #if __has_feature(objc_arc) #define retain_stub self #define autorelease_stub self #define release_stub self #define dealloc_stub self #define bridge_stub __bridge #else #define retain_stub retain #define autorelease_stub autorelease #define release_stub release #define dealloc_stub dealloc #define bridge_stub #endif #endif
          Hide
          Mike Riley added a comment -

          Hirano: This worked beautifully, no issues, even mixing -fno-objc-arc flagged files in with those using arc had no problem in my project. I've been using it for a few weeks. It's highly appreciated and ARC library compatibility is an obvious issue with any new Cocoa based projects.

          Jake: Have you had a chance to review this? The patch still works against the latest trunk. Also, I have a few things I'd like to commit eventually that depend on this, committing could save someone the trouble of rebasing.

          Show
          Mike Riley added a comment - Hirano: This worked beautifully, no issues, even mixing -fno-objc-arc flagged files in with those using arc had no problem in my project. I've been using it for a few weeks. It's highly appreciated and ARC library compatibility is an obvious issue with any new Cocoa based projects. Jake: Have you had a chance to review this? The patch still works against the latest trunk. Also, I have a few things I'd like to commit eventually that depend on this, committing could save someone the trouble of rebasing.
          Hide
          HIRANO Satoshi added a comment -

          I'd like to give some explanation about the ARC patch for iOS and MacOS.

          On 2011/11/14, at 14:36, HIRANO Satoshi wrote:
          >- Works for iOS and MacOS.
          >- The runtime and generated code are compatible with both ARC compilation
          > mode and non-ARC compilation mode.

          There is no compiler option for switching ARC and Non-ARC. It's fully automatic.

          You must use retain_stub/release_stub instead of retain/release when you alter the runtime.
          TObjective-C.h includes magic macros like this;

          #if __has_feature(objc_arc)
          #define retain_stub self
          #define release_stub self
          #else
          #define retain_stub retain
          #define release_stub release
          #endif

          o = [obj retain_stub] is replaced with
          o = [obj self] in case of ARC compilation.

          [obj release_stub] is replace with [obj self]. It takes a little bit time but not harmful.

          > - Initialization of struct/exception/map/list/set with defalut values is
          > implemented.

          The Cocoa (Objective-C) generator ignored default values in struct/map/list/set. I found the generated code did not include default initializer. For example, "nobody" is not set when you create a Person object even if you write like this;

          struct Person

          { 1: string name = "nobody", 2: i32 age }

          I added some code to generate the default initializer like this. It should handle any nested combination of struct/exception/map/list/set.

          • (id) init { self = [super init]; [self setName:@"nobody"]; return self; }

          > - Now it generates much better code for initializing constants. The current
          > thrift compiler generates buggy code.

          The current compiler can compile this example, because generated code has initWithName:age:.

          const Person stationMaster =

          {'name' : "John", 'age' : 49 }

          But the following example fails, because generated code does not have initWithName:.

          const Person stationMaster =

          {'name' : "John"}

          I ported the latest code for generating constant initializer from Java generator. The new compiler does not use initWithXXXX, but uses property setters repeatedly and recursively instead.

          There are some more bug fixes.

          I found memory leak in transport/TSocketClient.m. I fixed it by adding two CFRelease()s.

          Objective-C compiler complains that transport/TSocketClient is not a compliant of NSStreamDelegate. I fixed it with proper #ifdef. This problem is mentioned in the following JIRA page but not fixed.

          https://issues.apache.org/jira/browse/THRIFT-762

          Have fun!

          hirano

          Show
          HIRANO Satoshi added a comment - I'd like to give some explanation about the ARC patch for iOS and MacOS. On 2011/11/14, at 14:36, HIRANO Satoshi wrote: >- Works for iOS and MacOS. >- The runtime and generated code are compatible with both ARC compilation > mode and non-ARC compilation mode. There is no compiler option for switching ARC and Non-ARC. It's fully automatic. You must use retain_stub/release_stub instead of retain/release when you alter the runtime. TObjective-C.h includes magic macros like this; #if __has_feature(objc_arc) #define retain_stub self #define release_stub self #else #define retain_stub retain #define release_stub release #endif o = [obj retain_stub] is replaced with o = [obj self] in case of ARC compilation. [obj release_stub] is replace with [obj self] . It takes a little bit time but not harmful. > - Initialization of struct/exception/map/list/set with defalut values is > implemented. The Cocoa (Objective-C) generator ignored default values in struct/map/list/set. I found the generated code did not include default initializer. For example, "nobody" is not set when you create a Person object even if you write like this; struct Person { 1: string name = "nobody", 2: i32 age } I added some code to generate the default initializer like this. It should handle any nested combination of struct/exception/map/list/set. (id) init { self = [super init]; [self setName:@"nobody"]; return self; } > - Now it generates much better code for initializing constants. The current > thrift compiler generates buggy code. The current compiler can compile this example, because generated code has initWithName:age:. const Person stationMaster = {'name' : "John", 'age' : 49 } But the following example fails, because generated code does not have initWithName:. const Person stationMaster = {'name' : "John"} I ported the latest code for generating constant initializer from Java generator. The new compiler does not use initWithXXXX, but uses property setters repeatedly and recursively instead. There are some more bug fixes. I found memory leak in transport/TSocketClient.m. I fixed it by adding two CFRelease()s. Objective-C compiler complains that transport/TSocketClient is not a compliant of NSStreamDelegate. I fixed it with proper #ifdef. This problem is mentioned in the following JIRA page but not fixed. https://issues.apache.org/jira/browse/THRIFT-762 Have fun! hirano
          Hide
          Jake Farrell added a comment -

          initial glance looks good, will test this tonight

          Show
          Jake Farrell added a comment - initial glance looks good, will test this tonight
          Hide
          HIRANO Satoshi added a comment -

          (Cocoa) Patch for adding support of ARC, initializing constants, initializing struct/map/list/set with default values

          I confirmed that the generated code from test/*.thrift passes code analyzer and can be compiled without warning.

          • t_cocoa_generator.cc
          • Generates code compatible with both ARC (Automatic Reference Counting) compilation mode and non-ARC compilation mode.
          • Initializes struct/exception/map/list/set with defalut values.
          • Generates much better code for initializing constants.
          • lib/cocoa/src/transport/TSocketClient.h
          • get rid of warning on NSStreamDelegate
          • lib/cocoa
          • works with both ARC (Automatic Reference Counting) compilation mode and non-ARC compilation mode.
          Show
          HIRANO Satoshi added a comment - (Cocoa) Patch for adding support of ARC, initializing constants, initializing struct/map/list/set with default values I confirmed that the generated code from test/*.thrift passes code analyzer and can be compiled without warning. t_cocoa_generator.cc Generates code compatible with both ARC (Automatic Reference Counting) compilation mode and non-ARC compilation mode. Initializes struct/exception/map/list/set with defalut values. Generates much better code for initializing constants. lib/cocoa/src/transport/TSocketClient.h get rid of warning on NSStreamDelegate lib/cocoa works with both ARC (Automatic Reference Counting) compilation mode and non-ARC compilation mode.
          Hide
          HIRANO Satoshi added a comment -

          I'm working on it and almost finished. Now generated code can be compiled by both ARC and Non-ARC compiler.

          I found the code for const initialization is so buggy and ARC compiler complains about it. I'm porting the latest initialization code from Java generator to Objective-C generator.

          Please wait for my patch.

          hirano 11 Nov. 2011

          Show
          HIRANO Satoshi added a comment - I'm working on it and almost finished. Now generated code can be compiled by both ARC and Non-ARC compiler. I found the code for const initialization is so buggy and ARC compiler complains about it. I'm porting the latest initialization code from Java generator to Objective-C generator. Please wait for my patch. hirano 11 Nov. 2011

            People

            • Assignee:
              HIRANO Satoshi
              Reporter:
              HIRANO Satoshi
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 24h
                24h
                Remaining:
                Remaining Estimate - 24h
                24h
                Logged:
                Time Spent - Not Specified
                Not Specified

                  Development